@shophost/rest-api 2.0.34 → 2.0.36

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 (220) hide show
  1. package/LICENSE +17 -13
  2. package/README.md +76 -66
  3. package/package.json +2 -2
  4. package/scripts/minify-dist.mjs +45 -0
  5. package/src/app.js +1 -53
  6. package/src/app.js.map +1 -1
  7. package/src/core/auth/auth.schema.js +1 -41
  8. package/src/core/auth/auth.util.js +1 -44
  9. package/src/core/auth/better-auth.lib.js +1 -100
  10. package/src/core/auth/generate-password-hash.util.js +1 -30
  11. package/src/core/auth/headers.schema.js +1 -22
  12. package/src/core/auth/user.schema.js +1 -30
  13. package/src/core/db/__generated__/client/browser.js +1 -18
  14. package/src/core/db/__generated__/client/client.js +1 -35
  15. package/src/core/db/__generated__/client/commonInputTypes.js +1 -11
  16. package/src/core/db/__generated__/client/enums.js +1 -200
  17. package/src/core/db/__generated__/client/internal/class.js +769 -55
  18. package/src/core/db/__generated__/client/internal/prismaNamespace.d.ts +2 -2
  19. package/src/core/db/__generated__/client/internal/prismaNamespace.js +1 -541
  20. package/src/core/db/__generated__/client/internal/prismaNamespaceBrowser.js +1 -512
  21. package/src/core/db/__generated__/client/models/Account.d.ts +0 -5
  22. package/src/core/db/__generated__/client/models/Account.js +1 -2
  23. package/src/core/db/__generated__/client/models/Address.d.ts +0 -5
  24. package/src/core/db/__generated__/client/models/Address.js +1 -2
  25. package/src/core/db/__generated__/client/models/Campaign.d.ts +0 -5
  26. package/src/core/db/__generated__/client/models/Campaign.js +1 -2
  27. package/src/core/db/__generated__/client/models/ClosingTimes.d.ts +0 -5
  28. package/src/core/db/__generated__/client/models/ClosingTimes.js +1 -2
  29. package/src/core/db/__generated__/client/models/File.d.ts +0 -5
  30. package/src/core/db/__generated__/client/models/File.js +1 -2
  31. package/src/core/db/__generated__/client/models/Invitation.d.ts +0 -5
  32. package/src/core/db/__generated__/client/models/Invitation.js +1 -2
  33. package/src/core/db/__generated__/client/models/LegalEntity.d.ts +0 -5
  34. package/src/core/db/__generated__/client/models/LegalEntity.js +1 -2
  35. package/src/core/db/__generated__/client/models/Manufacturer.d.ts +0 -5
  36. package/src/core/db/__generated__/client/models/Manufacturer.js +1 -2
  37. package/src/core/db/__generated__/client/models/ManufacturerTranslation.d.ts +0 -5
  38. package/src/core/db/__generated__/client/models/ManufacturerTranslation.js +1 -2
  39. package/src/core/db/__generated__/client/models/Member.d.ts +0 -5
  40. package/src/core/db/__generated__/client/models/Member.js +1 -2
  41. package/src/core/db/__generated__/client/models/Modifier.d.ts +0 -5
  42. package/src/core/db/__generated__/client/models/Modifier.js +1 -2
  43. package/src/core/db/__generated__/client/models/ModifierGroup.d.ts +0 -5
  44. package/src/core/db/__generated__/client/models/ModifierGroup.js +1 -2
  45. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.d.ts +0 -5
  46. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.js +1 -2
  47. package/src/core/db/__generated__/client/models/OpeningTimes.d.ts +0 -5
  48. package/src/core/db/__generated__/client/models/OpeningTimes.js +1 -2
  49. package/src/core/db/__generated__/client/models/Order.d.ts +0 -5
  50. package/src/core/db/__generated__/client/models/Order.js +1 -2
  51. package/src/core/db/__generated__/client/models/OrderItem.d.ts +0 -5
  52. package/src/core/db/__generated__/client/models/OrderItem.js +1 -2
  53. package/src/core/db/__generated__/client/models/OrderItemTranslation.d.ts +0 -5
  54. package/src/core/db/__generated__/client/models/OrderItemTranslation.js +1 -2
  55. package/src/core/db/__generated__/client/models/Organization.d.ts +0 -5
  56. package/src/core/db/__generated__/client/models/Organization.js +1 -2
  57. package/src/core/db/__generated__/client/models/OrganizationConfiguration.d.ts +0 -5
  58. package/src/core/db/__generated__/client/models/OrganizationConfiguration.js +1 -2
  59. package/src/core/db/__generated__/client/models/Payment.d.ts +0 -5
  60. package/src/core/db/__generated__/client/models/Payment.js +1 -2
  61. package/src/core/db/__generated__/client/models/PaymentSession.d.ts +0 -5
  62. package/src/core/db/__generated__/client/models/PaymentSession.js +1 -2
  63. package/src/core/db/__generated__/client/models/Product.d.ts +0 -5
  64. package/src/core/db/__generated__/client/models/Product.js +1 -2
  65. package/src/core/db/__generated__/client/models/ProductCategory.d.ts +0 -5
  66. package/src/core/db/__generated__/client/models/ProductCategory.js +1 -2
  67. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.d.ts +0 -5
  68. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.js +1 -2
  69. package/src/core/db/__generated__/client/models/ProductSnapshot.d.ts +0 -5
  70. package/src/core/db/__generated__/client/models/ProductSnapshot.js +1 -2
  71. package/src/core/db/__generated__/client/models/ProductTranslation.d.ts +0 -5
  72. package/src/core/db/__generated__/client/models/ProductTranslation.js +1 -2
  73. package/src/core/db/__generated__/client/models/Reservation.d.ts +0 -5
  74. package/src/core/db/__generated__/client/models/Reservation.js +1 -2
  75. package/src/core/db/__generated__/client/models/Session.d.ts +0 -5
  76. package/src/core/db/__generated__/client/models/Session.js +1 -2
  77. package/src/core/db/__generated__/client/models/ShippingMethod.d.ts +0 -5
  78. package/src/core/db/__generated__/client/models/ShippingMethod.js +1 -2
  79. package/src/core/db/__generated__/client/models/ShippingZone.d.ts +0 -5
  80. package/src/core/db/__generated__/client/models/ShippingZone.js +1 -2
  81. package/src/core/db/__generated__/client/models/User.d.ts +0 -5
  82. package/src/core/db/__generated__/client/models/User.js +1 -2
  83. package/src/core/db/__generated__/client/models/Verification.d.ts +0 -5
  84. package/src/core/db/__generated__/client/models/Verification.js +1 -2
  85. package/src/core/db/__generated__/client/models.js +1 -2
  86. package/src/core/db/index.js +1 -2
  87. package/src/core/email/components.d.ts +16 -0
  88. package/src/core/email/components.js +1 -0
  89. package/src/core/email/components.js.map +1 -0
  90. package/src/core/exceptions/http-exception.js +1 -9
  91. package/src/core/hono/hono.js +1 -123
  92. package/src/core/lib/prisma.d.ts +8 -8
  93. package/src/core/lib/prisma.js +1 -11
  94. package/src/core/logging/pino.js +1 -5
  95. package/src/core/notifications/email.service.js +1 -116
  96. package/src/core/openapi/openapi.lib.js +1 -26
  97. package/src/core/types/google-maps.types.js +1 -2
  98. package/src/core/utils/currency.util.js +1 -11
  99. package/src/core/utils/env.util.js +1 -8
  100. package/src/core/utils/object.util.js +1 -39
  101. package/src/core/utils/translations.util.js +0 -1
  102. package/src/core/utils/zod.util.js +1 -85
  103. package/src/db.js +1 -3
  104. package/src/features/access/access.handler.js +1 -91
  105. package/src/features/access/access.route.js +1 -220
  106. package/src/features/access/access.schema.js +1 -108
  107. package/src/features/access/access.service.js +1 -294
  108. package/src/features/analytics/analytics.handler.d.ts +2 -0
  109. package/src/features/analytics/analytics.handler.js +1 -0
  110. package/src/features/analytics/analytics.handler.js.map +1 -0
  111. package/src/features/analytics/analytics.route.d.ts +3 -0
  112. package/src/features/analytics/analytics.route.js +1 -0
  113. package/src/features/analytics/analytics.route.js.map +1 -0
  114. package/src/features/analytics/analytics.schema.d.ts +86 -0
  115. package/src/features/analytics/analytics.schema.js +1 -0
  116. package/src/features/analytics/analytics.schema.js.map +1 -0
  117. package/src/features/analytics/analytics.service.d.ts +45 -0
  118. package/src/features/analytics/analytics.service.js +1 -0
  119. package/src/features/analytics/analytics.service.js.map +1 -0
  120. package/src/features/cart/cart.handler.js +1 -17
  121. package/src/features/cart/cart.route.js +1 -32
  122. package/src/features/cart/cart.schema.d.ts +1 -1
  123. package/src/features/cart/cart.schema.js +1 -39
  124. package/src/features/cart/cart.service.d.ts +1 -1
  125. package/src/features/cart/cart.service.js +1 -97
  126. package/src/features/cart/cart.util.js +1 -76
  127. package/src/features/file/file.handler.js +1 -23
  128. package/src/features/file/file.route.js +1 -34
  129. package/src/features/file/file.schema.js +1 -77
  130. package/src/features/file/file.service.js +1 -66
  131. package/src/features/health/health.handler.js +1 -10
  132. package/src/features/health/health.route.js +1 -25
  133. package/src/features/index.d.ts +1 -0
  134. package/src/features/index.js +1 -16
  135. package/src/features/index.js.map +1 -1
  136. package/src/features/location/location.handler.js +1 -25
  137. package/src/features/location/location.route.js +1 -56
  138. package/src/features/location/location.schema.js +1 -50
  139. package/src/features/location/location.service.js +1 -141
  140. package/src/features/manufacturer/manufacturer.handler.js +1 -53
  141. package/src/features/manufacturer/manufacturer.route.js +1 -97
  142. package/src/features/manufacturer/manufacturer.schema.js +1 -125
  143. package/src/features/manufacturer/manufacturer.service.js +1 -190
  144. package/src/features/order/emails/order-confirmation.email.js +1 -229
  145. package/src/features/order/emails/order-confirmation.email.js.map +1 -1
  146. package/src/features/order/emails/order-notification.email.js +1 -229
  147. package/src/features/order/emails/order-notification.email.js.map +1 -1
  148. package/src/features/order/fulfilment.schema.js +1 -3
  149. package/src/features/order/order.handler.js +1 -54
  150. package/src/features/order/order.route.js +1 -111
  151. package/src/features/order/order.schema.d.ts +4 -4
  152. package/src/features/order/order.schema.js +1 -158
  153. package/src/features/order/order.service.d.ts +4 -4
  154. package/src/features/order/order.service.js +1 -306
  155. package/src/features/order/recipient.schema.js +1 -38
  156. package/src/features/organization/legal-entity.schema.js +1 -83
  157. package/src/features/organization/organization-configuration.schema.js +1 -115
  158. package/src/features/organization/organization.handler.js +1 -48
  159. package/src/features/organization/organization.route.js +1 -84
  160. package/src/features/organization/organization.schema.js +1 -64
  161. package/src/features/organization/organization.service.js +1 -334
  162. package/src/features/payment/payment.handler.js +1 -16
  163. package/src/features/payment/payment.route.js +1 -22
  164. package/src/features/payment/payment.schema.d.ts +3 -3
  165. package/src/features/payment/payment.schema.js +1 -46
  166. package/src/features/payment/payment.service.d.ts +1 -1
  167. package/src/features/payment/payment.service.js +1 -100
  168. package/src/features/payment/stripe.service.js +1 -164
  169. package/src/features/product/product-modifier.schema.js +1 -84
  170. package/src/features/product/product.handler.js +1 -87
  171. package/src/features/product/product.route.js +1 -179
  172. package/src/features/product/product.schema.d.ts +3 -3
  173. package/src/features/product/product.schema.js +1 -143
  174. package/src/features/product/product.service.d.ts +2 -2
  175. package/src/features/product/product.service.js +1 -440
  176. package/src/features/product-category/product-category.handler.js +1 -59
  177. package/src/features/product-category/product-category.route.js +1 -139
  178. package/src/features/product-category/product-category.schema.js +1 -86
  179. package/src/features/product-category/product-category.service.js +1 -220
  180. package/src/features/reservation/emails/reservation-cancellation.email.js +1 -82
  181. package/src/features/reservation/emails/reservation-cancellation.email.js.map +1 -1
  182. package/src/features/reservation/emails/reservation-confirmation.email.js +1 -82
  183. package/src/features/reservation/emails/reservation-confirmation.email.js.map +1 -1
  184. package/src/features/reservation/emails/reservation-notification.email.js +1 -93
  185. package/src/features/reservation/emails/reservation-notification.email.js.map +1 -1
  186. package/src/features/reservation/reservation.handler.js +1 -65
  187. package/src/features/reservation/reservation.route.js +1 -167
  188. package/src/features/reservation/reservation.schema.d.ts +1 -1
  189. package/src/features/reservation/reservation.schema.js +1 -51
  190. package/src/features/reservation/reservation.service.js +1 -231
  191. package/src/features/shipping/shipping.handler.js +1 -32
  192. package/src/features/shipping/shipping.route.js +1 -51
  193. package/src/features/shipping/shipping.service.js +1 -96
  194. package/src/features/shipping-method/shipping-method.handler.js +1 -60
  195. package/src/features/shipping-method/shipping-method.route.js +1 -144
  196. package/src/features/shipping-method/shipping-method.schema.js +1 -48
  197. package/src/features/shipping-method/shipping-method.service.js +1 -229
  198. package/src/features/shipping-method/shipping-zone.schema.js +1 -31
  199. package/src/features/webhook/webhook.handler.js +1 -50
  200. package/src/features/webhook/webhook.route.js +1 -33
  201. package/src/index.js +1 -6
  202. package/src/integrations/next.js +1 -82
  203. package/src/schemas/address.schema.js +1 -112
  204. package/src/schemas/currency.schema.js +1 -118
  205. package/src/schemas/error.schema.js +1 -12
  206. package/src/schemas/index.d.ts +1 -0
  207. package/src/schemas/index.js +1 -29
  208. package/src/schemas/index.js.map +1 -1
  209. package/src/schemas/locales.schema.js +1 -238
  210. package/src/schemas/number.schema.js +1 -29
  211. package/src/schemas/pagination.schema.js +1 -54
  212. package/src/schemas/params.schema.js +1 -20
  213. package/src/schemas/queries.schema.js +1 -6
  214. package/src/test/global-setup.js +1 -37
  215. package/src/test/integration/api-fixtures.js +1 -160
  216. package/src/test/integration/seed.js +1 -368
  217. package/src/test/integration/test-helpers.d.ts +2 -0
  218. package/src/test/integration/test-helpers.js +1 -154
  219. package/src/test/integration/test-helpers.js.map +1 -1
  220. package/src/test/setup-test-env.js +1 -7
@@ -0,0 +1,86 @@
1
+ import { z } from "@hono/zod-openapi";
2
+ export declare const AnalyticsOverviewQuerySchema: z.ZodObject<{
3
+ from: z.ZodCoercedDate<unknown>;
4
+ to: z.ZodCoercedDate<unknown>;
5
+ }, z.core.$strip>;
6
+ export declare const AnalyticsOverviewSchema: z.ZodObject<{
7
+ range: z.ZodObject<{
8
+ from: z.ZodDate;
9
+ to: z.ZodDate;
10
+ }, z.core.$strip>;
11
+ summary: z.ZodObject<{
12
+ currency: z.ZodEnum<{
13
+ USD: "USD";
14
+ EUR: "EUR";
15
+ GBP: "GBP";
16
+ JPY: "JPY";
17
+ AUD: "AUD";
18
+ CAD: "CAD";
19
+ CHF: "CHF";
20
+ CNY: "CNY";
21
+ SEK: "SEK";
22
+ NZD: "NZD";
23
+ MXN: "MXN";
24
+ SGD: "SGD";
25
+ HKD: "HKD";
26
+ NOK: "NOK";
27
+ KRW: "KRW";
28
+ TRY: "TRY";
29
+ RUB: "RUB";
30
+ INR: "INR";
31
+ BRL: "BRL";
32
+ ZAR: "ZAR";
33
+ DKK: "DKK";
34
+ PLN: "PLN";
35
+ THB: "THB";
36
+ IDR: "IDR";
37
+ HUF: "HUF";
38
+ CZK: "CZK";
39
+ ILS: "ILS";
40
+ PHP: "PHP";
41
+ AED: "AED";
42
+ COP: "COP";
43
+ SAR: "SAR";
44
+ MYR: "MYR";
45
+ RON: "RON";
46
+ }>;
47
+ totalSales: z.ZodNumber;
48
+ paidOrders: z.ZodNumber;
49
+ averageOrderValue: z.ZodNumber;
50
+ reservations: z.ZodNumber;
51
+ guests: z.ZodNumber;
52
+ }, z.core.$strip>;
53
+ salesByDay: z.ZodArray<z.ZodObject<{
54
+ date: z.ZodDate;
55
+ label: z.ZodString;
56
+ totalSales: z.ZodNumber;
57
+ paidOrders: z.ZodNumber;
58
+ }, z.core.$strip>>;
59
+ reservationsByDay: z.ZodArray<z.ZodObject<{
60
+ date: z.ZodDate;
61
+ label: z.ZodString;
62
+ reservations: z.ZodNumber;
63
+ guests: z.ZodNumber;
64
+ }, z.core.$strip>>;
65
+ paymentMethods: z.ZodArray<z.ZodObject<{
66
+ method: z.ZodEnum<{
67
+ card: "card";
68
+ blik: "blik";
69
+ paypal: "paypal";
70
+ bank_transfer: "bank_transfer";
71
+ cash_on_delivery: "cash_on_delivery";
72
+ }>;
73
+ count: z.ZodNumber;
74
+ totalSales: z.ZodNumber;
75
+ }, z.core.$strip>>;
76
+ fulfilmentMethods: z.ZodArray<z.ZodObject<{
77
+ method: z.ZodEnum<{
78
+ delivery: "delivery";
79
+ pickup: "pickup";
80
+ }>;
81
+ count: z.ZodNumber;
82
+ totalSales: z.ZodNumber;
83
+ }, z.core.$strip>>;
84
+ }, z.core.$strip>;
85
+ export type AnalyticsOverview = z.infer<typeof AnalyticsOverviewSchema>;
86
+ export type AnalyticsOverviewQuery = z.infer<typeof AnalyticsOverviewQuerySchema>;
@@ -0,0 +1 @@
1
+ import{z as e}from"@hono/zod-openapi";import{currency as t}from"../../schemas/currency.schema";import{fulfilmentMethod as n}from"../order/fulfilment.schema";const a=e.enum(["card","blik","paypal","bank_transfer","cash_on_delivery"]).openapi({description:"The payment method used for the order",example:"card"});export const AnalyticsOverviewQuerySchema=e.object({from:e.coerce.date().openapi({description:"Start of the reporting range",example:"2026-01-01T00:00:00.000Z"}),to:e.coerce.date().openapi({description:"End of the reporting range",example:"2026-01-30T23:59:59.999Z"})});const r=e.object({from:e.date(),to:e.date()}).openapi("AnalyticsRange"),o=e.object({currency:t,totalSales:e.number().min(0),paidOrders:e.number().int().min(0),averageOrderValue:e.number().min(0),reservations:e.number().int().min(0),guests:e.number().int().min(0)}).openapi("AnalyticsSummary"),i=e.object({date:e.date(),label:e.string(),totalSales:e.number().min(0),paidOrders:e.number().int().min(0)}).openapi("SalesByDayPoint"),m=e.object({date:e.date(),label:e.string(),reservations:e.number().int().min(0),guests:e.number().int().min(0)}).openapi("ReservationsByDayPoint"),s=e.object({method:a,count:e.number().int().min(0),totalSales:e.number().min(0)}).openapi("PaymentMethodBreakdownItem"),c=e.object({method:n,count:e.number().int().min(0),totalSales:e.number().min(0)}).openapi("FulfilmentBreakdownItem");export const AnalyticsOverviewSchema=e.object({range:r,summary:o,salesByDay:e.array(i),reservationsByDay:e.array(m),paymentMethods:e.array(s),fulfilmentMethods:e.array(c)}).openapi("AnalyticsOverview");
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.schema.js","sourceRoot":"","sources":["../../../../../../packages/rest-api/src/features/analytics/analytics.schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { PrismaClientType } from "../../core/lib/prisma";
2
+ declare class AnalyticsService {
3
+ private readonly prisma;
4
+ constructor(prisma: PrismaClientType);
5
+ getOverview(organizationId: string, query: {
6
+ from: Date;
7
+ to: Date;
8
+ }): Promise<{
9
+ range: {
10
+ from: Date;
11
+ to: Date;
12
+ };
13
+ summary: {
14
+ currency: "USD" | "EUR" | "GBP" | "JPY" | "AUD" | "CAD" | "CHF" | "CNY" | "SEK" | "NZD" | "MXN" | "SGD" | "HKD" | "NOK" | "KRW" | "TRY" | "RUB" | "INR" | "BRL" | "ZAR" | "DKK" | "PLN" | "THB" | "IDR" | "HUF" | "CZK" | "ILS" | "PHP" | "AED" | "COP" | "SAR" | "MYR" | "RON";
15
+ totalSales: number;
16
+ paidOrders: number;
17
+ averageOrderValue: number;
18
+ reservations: number;
19
+ guests: number;
20
+ };
21
+ salesByDay: {
22
+ date: Date;
23
+ label: string;
24
+ totalSales: number;
25
+ paidOrders: number;
26
+ }[];
27
+ reservationsByDay: {
28
+ date: Date;
29
+ label: string;
30
+ reservations: number;
31
+ guests: number;
32
+ }[];
33
+ paymentMethods: {
34
+ method: "card" | "blik" | "paypal" | "bank_transfer" | "cash_on_delivery";
35
+ count: number;
36
+ totalSales: number;
37
+ }[];
38
+ fulfilmentMethods: {
39
+ method: "delivery" | "pickup";
40
+ count: number;
41
+ totalSales: number;
42
+ }[];
43
+ }>;
44
+ }
45
+ export { AnalyticsService };
@@ -0,0 +1 @@
1
+ import{__awaiter as B}from"tslib";import{eachDayOfInterval as k,endOfDay as E,format as l,startOfDay as I}from"date-fns";import{HttpException as _}from"../../core/exceptions/http-exception";import{AnalyticsOverviewSchema as K}from"./analytics.schema";class P{constructor(o){this.prisma=o}getOverview(o,h){return B(this,void 0,void 0,function*(){var c,u,y,m;const n=I(h.from),r=E(h.to);if(n>r)throw new _(400,"`from` must be before or equal to `to`");const g=yield this.prisma.organization.findFirst({where:{id:o},include:{configuration:!0}});if(!g)throw new _(404,"Organization not found");const[b,x]=yield Promise.all([this.prisma.order.findMany({where:{organizationId:o,deletedAt:null,createdAt:{gte:n,lte:r}},select:{createdAt:!0,cancelledAt:!0,fulfilmentMethod:!0,payment:{select:{method:!0,status:!0,total:!0}}}}),this.prisma.reservation.findMany({where:{organizationId:o,date:{gte:n,lte:r}},select:{date:!0,guests:!0,cancelledAt:!0}})]),S=k({start:n,end:r}),d=S.map(t=>({date:t,label:l(t,"MMM d"),totalSales:0,paidOrders:0})),f=S.map(t=>({date:t,label:l(t,"MMM d"),reservations:0,guests:0})),w=new Map(d.map((t,e)=>[l(t.date,"yyyy-MM-dd"),e])),p=new Map,A=new Map(["delivery","pickup"].map(t=>[t,{method:t,count:0,totalSales:0}]));let v=0,i=0;for(const t of b){const e=t.cancelledAt===null&&((c=t.payment)===null||c===void 0?void 0:c.status)==="succeeded",s=l(t.createdAt,"yyyy-MM-dd"),M=w.get(s);if(e&&t.payment&&M!==void 0){d[M].totalSales+=t.payment.total,d[M].paidOrders+=1,v+=t.payment.total,i+=1;const a=(u=p.get(t.payment.method))!==null&&u!==void 0?u:{method:t.payment.method,count:0,totalSales:0};a.count+=1,a.totalSales+=t.payment.total,p.set(t.payment.method,a)}if(t.cancelledAt===null&&t.fulfilmentMethod){const a=A.get(t.fulfilmentMethod);a&&(a.count+=1,a.totalSales+=(m=(y=t.payment)===null||y===void 0?void 0:y.total)!==null&&m!==void 0?m:0)}}let O=0,D=0;for(const t of x){if(t.cancelledAt)continue;const e=l(t.date,"yyyy-MM-dd"),s=w.get(e);s!==void 0&&(f[s].reservations+=1,f[s].guests+=t.guests,O+=1,D+=t.guests)}return K.parse({range:{from:n,to:r},summary:{currency:g.configuration.defaultCurrency,totalSales:v,paidOrders:i,averageOrderValue:i>0?v/i:0,reservations:O,guests:D},salesByDay:d,reservationsByDay:f,paymentMethods:Array.from(p.values()).sort((t,e)=>e.totalSales-t.totalSales),fulfilmentMethods:Array.from(A.values()).sort((t,e)=>e.totalSales-t.totalSales)})})}}export{P as AnalyticsService};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.service.js","sourceRoot":"","sources":["../../../../../../packages/rest-api/src/features/analytics/analytics.service.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { createApiRouter } from "../../core/hono/hono";
3
- import { cartRoute } from "./cart.route";
4
- import { CartService } from "./cart.service";
5
- export const buildCartHandler = (prisma) => {
6
- const app = createApiRouter();
7
- app.openapi(cartRoute.getCartData, (c) => __awaiter(void 0, void 0, void 0, function* () {
8
- const params = c.req.valid("param");
9
- const body = c.req.valid("json");
10
- const query = c.req.valid("query");
11
- const service = new CartService(prisma);
12
- const productMapping = yield service.getCartData(params.organizationId, body, query);
13
- return c.json(productMapping, 200);
14
- }));
15
- return app;
16
- };
17
- //# sourceMappingURL=cart.handler.js.map
1
+ import{__awaiter as p}from"tslib";import{createApiRouter as d}from"../../core/hono/hono";import{cartRoute as s}from"./cart.route";import{CartService as c}from"./cart.service";export const buildCartHandler=o=>{const t=d();return t.openapi(s.getCartData,r=>p(void 0,void 0,void 0,function*(){const a=r.req.valid("param"),e=r.req.valid("json"),i=r.req.valid("query"),n=yield new c(o).getCartData(a.organizationId,e,i);return r.json(n,200)})),t};
@@ -1,32 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { createApiRoute } from "../../core/hono/hono";
3
- import { CartProductsMappingSchema, CartSchema, ErrorSchema, HeaderSchema, locale, OrganizationParams, } from "../../schemas";
4
- const getCartDataRoute = createApiRoute({
5
- body: CartSchema,
6
- description: "Fetches formatted cart data",
7
- headers: HeaderSchema,
8
- method: "POST",
9
- operationId: "getCartData",
10
- path: "/:organizationId/cart",
11
- pathParams: OrganizationParams,
12
- query: z.object({
13
- locale: locale.default("en"),
14
- }),
15
- responses: {
16
- 200: z.object({
17
- invalidProductIds: z.array(z.string()),
18
- products: CartProductsMappingSchema,
19
- shipping: z.number().optional(),
20
- subtotal: z.number(),
21
- total: z.number(),
22
- }),
23
- 400: ErrorSchema,
24
- 401: ErrorSchema,
25
- },
26
- summary: "Get Formatted Cart",
27
- tags: ["Cart"],
28
- });
29
- export const cartRoute = {
30
- getCartData: getCartDataRoute,
31
- };
32
- //# sourceMappingURL=cart.route.js.map
1
+ import{z as t}from"@hono/zod-openapi";import{createApiRoute as r}from"../../core/hono/hono";import{CartProductsMappingSchema as e,CartSchema as o,ErrorSchema as a,HeaderSchema as m,locale as c,OrganizationParams as i}from"../../schemas";const n=r({body:o,description:"Fetches formatted cart data",headers:m,method:"POST",operationId:"getCartData",path:"/:organizationId/cart",pathParams:i,query:t.object({locale:c.default("en")}),responses:{200:t.object({invalidProductIds:t.array(t.string()),products:e,shipping:t.number().optional(),subtotal:t.number(),total:t.number()}),400:a,401:a},summary:"Get Formatted Cart",tags:["Cart"]});export const cartRoute={getCartData:n};
@@ -2,6 +2,7 @@ import { z } from "@hono/zod-openapi";
2
2
  export declare const CartProductsMappingSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
3
3
  description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
4
4
  title: z.ZodDefault<z.ZodString>;
5
+ currency: z.ZodString;
5
6
  id: z.ZodString;
6
7
  createdAt: z.ZodDate;
7
8
  slug: z.ZodOptional<z.ZodString>;
@@ -9,7 +10,6 @@ export declare const CartProductsMappingSchema: z.ZodRecord<z.ZodString, z.ZodOb
9
10
  sku: z.ZodOptional<z.ZodString>;
10
11
  basePrice: z.ZodCoercedNumber<unknown>;
11
12
  discountedBasePrice: z.ZodPipe<z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>, z.ZodTransform<string | number | null, string | number | null | undefined>>, z.ZodNullable<z.ZodNumber>>;
12
- currency: z.ZodString;
13
13
  images: z.ZodOptional<z.ZodArray<z.ZodObject<{
14
14
  id: z.ZodString;
15
15
  url: z.ZodString;
@@ -1,39 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { LocalizedProductSchema } from "../product/product.schema";
3
- export const CartProductsMappingSchema = z.record(z.string().openapi({
4
- example: "clf9876543210abcdef",
5
- description: "ID of the product in the cart",
6
- }), LocalizedProductSchema);
7
- export const CartItemSchema = z
8
- .object({
9
- productId: z.string().cuid().openapi({
10
- example: "clf9876543210abcdef",
11
- description: "ID of the product in the cart",
12
- }),
13
- quantity: z.number().default(1).optional().openapi({
14
- example: 2,
15
- description: "Quantity of this item in the cart",
16
- }),
17
- modifierGroups: z.array(z.object({
18
- id: z.string().cuid().openapi({
19
- example: "clg1234567890abcdef",
20
- description: "ID of the modifier group",
21
- }),
22
- modifiers: z.array(z.object({
23
- id: z.string().cuid().openapi({
24
- example: "clh9876543210abcdef",
25
- description: "ID of the selected modifier",
26
- }),
27
- quantity: z.number().default(1).openapi({
28
- example: 1,
29
- description: "Quantity of this modifier",
30
- }),
31
- })),
32
- })),
33
- })
34
- .openapi("CartItem");
35
- export const CartSchema = z.object({
36
- items: z.array(CartItemSchema),
37
- shippingMethodId: z.string().cuid().optional(),
38
- });
39
- //# sourceMappingURL=cart.schema.js.map
1
+ import{z as e}from"@hono/zod-openapi";import{LocalizedProductSchema as t}from"../product/product.schema";export const CartProductsMappingSchema=e.record(e.string().openapi({example:"clf9876543210abcdef",description:"ID of the product in the cart"}),t),CartItemSchema=e.object({productId:e.string().cuid().openapi({example:"clf9876543210abcdef",description:"ID of the product in the cart"}),quantity:e.number().default(1).optional().openapi({example:2,description:"Quantity of this item in the cart"}),modifierGroups:e.array(e.object({id:e.string().cuid().openapi({example:"clg1234567890abcdef",description:"ID of the modifier group"}),modifiers:e.array(e.object({id:e.string().cuid().openapi({example:"clh9876543210abcdef",description:"ID of the selected modifier"}),quantity:e.number().default(1).openapi({example:1,description:"Quantity of this modifier"})}))}))}).openapi("CartItem"),CartSchema=e.object({items:e.array(CartItemSchema),shippingMethodId:e.string().cuid().optional()});
@@ -19,11 +19,11 @@ declare class CartService {
19
19
  products: Record<string, {
20
20
  description: string | null;
21
21
  title: string;
22
+ currency: string;
22
23
  id: string;
23
24
  createdAt: Date;
24
25
  basePrice: number;
25
26
  discountedBasePrice: number | null;
26
- currency: string;
27
27
  modifierGroups: {
28
28
  title: string | null;
29
29
  id: string;
@@ -1,97 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { flattenTranslationData } from "../../core/utils/zod.util";
3
- import { LocalizedProductSchema, } from "../../schemas";
4
- class CartService {
5
- constructor(prisma) {
6
- this.prisma = prisma;
7
- }
8
- /**
9
- * Calculate price breakdown for cart items
10
- */
11
- calculatePriceBreakdown(items, products, shippingMethodId) {
12
- return __awaiter(this, void 0, void 0, function* () {
13
- var _a, _b;
14
- const shippingMethod = shippingMethodId
15
- ? yield this.prisma.shippingMethod.findUnique({
16
- where: {
17
- id: shippingMethodId,
18
- },
19
- include: {
20
- shippingZones: true,
21
- },
22
- })
23
- : null;
24
- const subtotal = items.reduce((total, item) => {
25
- var _a, _b;
26
- const product = products.find((p) => p.id === item.productId);
27
- if (!product)
28
- return total;
29
- const price = (_b = (_a = product.discountedBasePrice) !== null && _a !== void 0 ? _a : product.basePrice) !== null && _b !== void 0 ? _b : 0;
30
- return total + price * (item.quantity || 1);
31
- }, 0);
32
- const shipping = (_a = shippingMethod === null || shippingMethod === void 0 ? void 0 : shippingMethod.shippingZones[0]) === null || _a === void 0 ? void 0 : _a.price;
33
- const total = subtotal + (shipping !== null && shipping !== void 0 ? shipping : 0);
34
- return {
35
- total,
36
- subtotal,
37
- shipping: (_b = shippingMethod === null || shippingMethod === void 0 ? void 0 : shippingMethod.shippingZones[0]) === null || _b === void 0 ? void 0 : _b.price,
38
- };
39
- });
40
- }
41
- /**
42
- * Get product mapping for cart items
43
- * This method takes cart items and returns a mapping of product IDs to localized product data
44
- */
45
- getCartData(organizationId, body, query) {
46
- return __awaiter(this, void 0, void 0, function* () {
47
- const { locale } = query;
48
- const productIds = new Set(body.items.map((item) => item.productId));
49
- const products = yield this.prisma.product.findMany({
50
- where: {
51
- id: { in: Array.from(productIds) },
52
- organizationId,
53
- deletedAt: null,
54
- publishedAt: {
55
- not: null,
56
- },
57
- },
58
- include: {
59
- translations: true,
60
- images: true,
61
- categories: {
62
- include: {
63
- translations: {
64
- where: {
65
- locale,
66
- },
67
- },
68
- },
69
- },
70
- modifierGroups: {
71
- include: {
72
- translations: {
73
- where: {
74
- locale,
75
- },
76
- },
77
- modifiers: true,
78
- },
79
- },
80
- },
81
- });
82
- const invalidProductIds = body.items
83
- .filter((item) => {
84
- const product = products.find((p) => p.id === item.productId);
85
- return !product;
86
- })
87
- .map((item) => item.productId);
88
- const paymentBreakdown = yield this.calculatePriceBreakdown(body.items, products, body.shippingMethodId);
89
- return Object.assign(Object.assign({}, paymentBreakdown), { invalidProductIds, products: products.reduce((acc, product) => {
90
- acc[product.id] = LocalizedProductSchema.parse(flattenTranslationData(product));
91
- return acc;
92
- }, {}) });
93
- });
94
- }
95
- }
96
- export { CartService };
97
- //# sourceMappingURL=cart.service.js.map
1
+ import{__awaiter as m}from"tslib";import{flattenTranslationData as g}from"../../core/utils/zod.util";import{LocalizedProductSchema as w}from"../../schemas";class I{constructor(o){this.prisma=o}calculatePriceBreakdown(o,e,c){return m(this,void 0,void 0,function*(){var r,d;const i=c?yield this.prisma.shippingMethod.findUnique({where:{id:c},include:{shippingZones:!0}}):null,u=o.reduce((n,a)=>{var l,p;const h=e.find(f=>f.id===a.productId);if(!h)return n;const v=(p=(l=h.discountedBasePrice)!==null&&l!==void 0?l:h.basePrice)!==null&&p!==void 0?p:0;return n+v*(a.quantity||1)},0),s=(r=i?.shippingZones[0])===null||r===void 0?void 0:r.price;return{total:u+(s??0),subtotal:u,shipping:(d=i?.shippingZones[0])===null||d===void 0?void 0:d.price}})}getCartData(o,e,c){return m(this,void 0,void 0,function*(){const{locale:r}=c,d=new Set(e.items.map(t=>t.productId)),i=yield this.prisma.product.findMany({where:{id:{in:Array.from(d)},organizationId:o,deletedAt:null,publishedAt:{not:null}},include:{translations:!0,images:!0,categories:{include:{translations:{where:{locale:r}}}},modifierGroups:{include:{translations:{where:{locale:r}},modifiers:!0}}}}),u=e.items.filter(t=>!i.find(a=>a.id===t.productId)).map(t=>t.productId),s=yield this.calculatePriceBreakdown(e.items,i,e.shippingMethodId);return Object.assign(Object.assign({},s),{invalidProductIds:u,products:i.reduce((t,n)=>(t[n.id]=w.parse(g(n)),t),{})})})}}export{I as CartService};
@@ -1,76 +1 @@
1
- import { __awaiter } from "tslib";
2
- export const transformCartItemToOrderItem = (prisma) => (item) => __awaiter(void 0, void 0, void 0, function* () {
3
- // Fetch the product with all necessary relations
4
- const product = yield prisma.product.findUnique({
5
- where: { id: item.productId },
6
- include: {
7
- translations: true,
8
- modifierGroups: {
9
- include: {
10
- translations: true,
11
- modifiers: true,
12
- },
13
- },
14
- images: true,
15
- },
16
- });
17
- if (!product) {
18
- throw new Error(`Product with ID ${item.productId} not found`);
19
- }
20
- const image = product.images[0];
21
- // Calculate the unit price (base price + modifiers)
22
- let unitPrice = product.basePrice;
23
- // Generate translations with title from product and subtitle from modifiers
24
- const translations = product.translations.map((translation) => {
25
- // Find all selected modifiers for this product
26
- const modifierSelections = [];
27
- // Process each modifier group
28
- item.modifierGroups.forEach((cartModifierGroup) => {
29
- var _a;
30
- // Find the corresponding product modifier group
31
- const productModifierGroup = product.modifierGroups.find((group) => group.id === cartModifierGroup.id);
32
- if (productModifierGroup) {
33
- // Get the translation for this modifier group
34
- const groupTranslation = productModifierGroup.translations.find((t) => t.locale === translation.locale);
35
- // Process each selected modifier
36
- const modifierTexts = [];
37
- cartModifierGroup.modifiers.forEach((cartModifier) => {
38
- // Find the corresponding product modifier
39
- const productModifier = productModifierGroup.modifiers.find((mod) => mod.id === cartModifier.id);
40
- if (productModifier) {
41
- // Add the modifier price to the unit price
42
- unitPrice += productModifier.price * cartModifier.quantity;
43
- // Add the modifier text
44
- modifierTexts.push(`${productModifier.title}${cartModifier.quantity > 1 ? ` (${cartModifier.quantity}x)` : ""}`);
45
- }
46
- });
47
- // Add the group and its modifiers to the selections
48
- if (modifierTexts.length > 0) {
49
- modifierSelections.push(`${(groupTranslation === null || groupTranslation === void 0 ? void 0 : groupTranslation.title) || ((_a = productModifierGroup.translations[0]) === null || _a === void 0 ? void 0 : _a.title) || ""}: ${modifierTexts.join(", ")}`);
50
- }
51
- }
52
- });
53
- // Create the subtitle from modifier selections
54
- const subtitle = modifierSelections.join(", ");
55
- return {
56
- locale: translation.locale,
57
- title: translation.title || "",
58
- subtitle: subtitle || "",
59
- };
60
- });
61
- // Calculate the total price based on quantity
62
- const quantity = item.quantity || 1;
63
- const totalPrice = unitPrice * quantity;
64
- return {
65
- translations: {
66
- create: translations,
67
- },
68
- unitPrice,
69
- totalPrice,
70
- quantity,
71
- rawData: item,
72
- imageId: image === null || image === void 0 ? void 0 : image.id,
73
- productSnapshotId: product.latestSnapshotId,
74
- };
75
- });
76
- //# sourceMappingURL=cart.util.js.map
1
+ import{__awaiter as q}from"tslib";export const transformCartItemToOrderItem=m=>o=>q(void 0,void 0,void 0,function*(){const t=yield m.product.findUnique({where:{id:o.productId},include:{translations:!0,modifierGroups:{include:{translations:!0,modifiers:!0}},images:!0}});if(!t)throw new Error(`Product with ID ${o.productId} not found`);const e=t.images[0];let s=t.basePrice;const h=t.translations.map(d=>{const f=[];o.modifierGroups.forEach(p=>{var a;const r=t.modifierGroups.find(n=>n.id===p.id);if(r){const n=r.translations.find(i=>i.locale===d.locale),u=[];p.modifiers.forEach(i=>{const l=r.modifiers.find(g=>g.id===i.id);l&&(s+=l.price*i.quantity,u.push(`${l.title}${i.quantity>1?` (${i.quantity}x)`:""}`))}),u.length>0&&f.push(`${n?.title||((a=r.translations[0])===null||a===void 0?void 0:a.title)||""}: ${u.join(", ")}`)}});const I=f.join(", ");return{locale:d.locale,title:d.title||"",subtitle:I||""}}),c=o.quantity||1,v=s*c;return{translations:{create:h},unitPrice:s,totalPrice:v,quantity:c,rawData:o,imageId:e?.id,productSnapshotId:t.latestSnapshotId}});
@@ -1,23 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { createApiRouter } from "../../core/hono/hono";
3
- import { fileRoute } from "./file.route";
4
- import { FileService } from "./file.service";
5
- export const buildFileHandler = (prisma) => {
6
- const app = createApiRouter();
7
- app.openapi(fileRoute.getVercelToken, (c) => __awaiter(void 0, void 0, void 0, function* () {
8
- const body = c.req.valid("json");
9
- const service = new FileService(prisma);
10
- const tokenResponse = yield service.getVercelToken(body, c.req.raw);
11
- return c.json(tokenResponse, 200);
12
- }));
13
- app.openapi(fileRoute.createTemporaryFile, (c) => __awaiter(void 0, void 0, void 0, function* () {
14
- const body = c.req.valid("json");
15
- const auth = c.get("auth");
16
- const user = yield auth.getCurrentUser();
17
- const service = new FileService(prisma);
18
- const file = yield service.createTemporaryFile(user.id, body);
19
- return c.json(file, 201);
20
- }));
21
- return app;
22
- };
23
- //# sourceMappingURL=file.handler.js.map
1
+ import{__awaiter as n}from"tslib";import{createApiRouter as l}from"../../core/hono/hono";import{fileRoute as s}from"./file.route";import{FileService as c}from"./file.service";export const buildFileHandler=i=>{const o=l();return o.openapi(s.getVercelToken,e=>n(void 0,void 0,void 0,function*(){const r=e.req.valid("json"),t=yield new c(i).getVercelToken(r,e.req.raw);return e.json(t,200)})),o.openapi(s.createTemporaryFile,e=>n(void 0,void 0,void 0,function*(){const r=e.req.valid("json"),t=yield e.get("auth").getCurrentUser(),d=yield new c(i).createTemporaryFile(t.id,r);return e.json(d,201)})),o};
@@ -1,34 +1 @@
1
- import { createApiRoute } from "../../core/hono/hono";
2
- import { CreateTemporaryFileSchema, FileSchema, GetVercelTokenBody, GetVercelTokenResponse, HeaderSchema, } from "../../schemas";
3
- const createTemporaryFileRoute = createApiRoute({
4
- body: CreateTemporaryFileSchema,
5
- description: "Creates a temporary file record and returns its ID",
6
- headers: HeaderSchema,
7
- method: "POST",
8
- operationId: "createTemporaryFile",
9
- path: "/files",
10
- responses: {
11
- 201: FileSchema,
12
- },
13
- summary: "Create Temporary File",
14
- tags: ["File"],
15
- });
16
- const getVercelTokenRoute = createApiRoute({
17
- body: GetVercelTokenBody,
18
- description: "Returns a Vercel token",
19
- headers: HeaderSchema,
20
- method: "POST",
21
- operationId: "getVercelToken",
22
- path: "/files/token/vercel",
23
- responses: {
24
- 200: GetVercelTokenResponse,
25
- 204: null,
26
- },
27
- summary: "Get Vercel Token",
28
- tags: ["File"],
29
- });
30
- export const fileRoute = {
31
- createTemporaryFile: createTemporaryFileRoute,
32
- getVercelToken: getVercelTokenRoute,
33
- };
34
- //# sourceMappingURL=file.route.js.map
1
+ import{createApiRoute as e}from"../../core/hono/hono";import{CreateTemporaryFileSchema as o,FileSchema as t,GetVercelTokenBody as a,GetVercelTokenResponse as s,HeaderSchema as r}from"../../schemas";const i=e({body:o,description:"Creates a temporary file record and returns its ID",headers:r,method:"POST",operationId:"createTemporaryFile",path:"/files",responses:{201:t},summary:"Create Temporary File",tags:["File"]}),l=e({body:a,description:"Returns a Vercel token",headers:r,method:"POST",operationId:"getVercelToken",path:"/files/token/vercel",responses:{200:s,204:null},summary:"Get Vercel Token",tags:["File"]});export const fileRoute={createTemporaryFile:i,getVercelToken:l};
@@ -1,77 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- const GenerateClientTokenEventSchema = z.object({
3
- type: z.literal("blob.generate-client-token"),
4
- payload: z.object({
5
- pathname: z.string(),
6
- callbackUrl: z.string(),
7
- multipart: z.boolean(),
8
- clientPayload: z.string().nullable(),
9
- }),
10
- });
11
- // Schema for UploadCompletedEvent
12
- const UploadCompletedEventSchema = z.object({
13
- type: z.literal("blob.upload-completed"),
14
- payload: z.object({
15
- // Replace z.any() with an appropriate schema for PutBlobResult if available
16
- blob: z.any(),
17
- tokenPayload: z.string().nullable().optional(),
18
- }),
19
- });
20
- // Discriminated union schema for HandleUploadBody
21
- export const GetVercelTokenBody = z.discriminatedUnion("type", [
22
- GenerateClientTokenEventSchema,
23
- UploadCompletedEventSchema,
24
- ]);
25
- export const GetVercelTokenResponse = z.discriminatedUnion("type", [
26
- z.object({
27
- type: z.literal("blob.generate-client-token"),
28
- clientToken: z.string(),
29
- }),
30
- z.object({
31
- type: z.literal("blob.upload-completed"),
32
- response: z.literal("ok"),
33
- }),
34
- ]);
35
- export const CreateTemporaryFileSchema = z.object({
36
- mimeType: z.string().min(1, "MIME type is required").openapi({
37
- example: "image/png",
38
- description: "MIME type of the file",
39
- }),
40
- size: z.number().min(1, "Size is required").openapi({
41
- example: 1024,
42
- description: "Size of the file in bytes",
43
- }),
44
- filename: z.string().min(1, "Filename is required").openapi({
45
- example: "example.png",
46
- description: "Name of the file",
47
- }),
48
- organizationId: z.string().optional().openapi({
49
- example: "clm1234567890abcdef",
50
- description: "ID of the organization",
51
- }),
52
- });
53
- export const FileSchema = z
54
- .object({
55
- id: z.string().min(1, "ID is required").openapi({
56
- example: "clf9876543210abcdef",
57
- description: "ID of the file",
58
- }),
59
- url: z.string().min(1, "Path is required").openapi({
60
- example: "/path/to/file",
61
- description: "Path of the file",
62
- }),
63
- mimeType: z.string().min(1, "MIME type is required").openapi({
64
- example: "image/png",
65
- description: "MIME type of the file",
66
- }),
67
- size: z.number().min(1, "Size is required").openapi({
68
- example: 1024,
69
- description: "Size of the file in bytes",
70
- }),
71
- filename: z.string().min(1, "Filename is required").openapi({
72
- example: "example.png",
73
- description: "Name of the file",
74
- }),
75
- })
76
- .openapi("UploadedFile");
77
- //# sourceMappingURL=file.schema.js.map
1
+ import{z as e}from"@hono/zod-openapi";const i=e.object({type:e.literal("blob.generate-client-token"),payload:e.object({pathname:e.string(),callbackUrl:e.string(),multipart:e.boolean(),clientPayload:e.string().nullable()})}),t=e.object({type:e.literal("blob.upload-completed"),payload:e.object({blob:e.any(),tokenPayload:e.string().nullable().optional()})});export const GetVercelTokenBody=e.discriminatedUnion("type",[i,t]),GetVercelTokenResponse=e.discriminatedUnion("type",[e.object({type:e.literal("blob.generate-client-token"),clientToken:e.string()}),e.object({type:e.literal("blob.upload-completed"),response:e.literal("ok")})]),CreateTemporaryFileSchema=e.object({mimeType:e.string().min(1,"MIME type is required").openapi({example:"image/png",description:"MIME type of the file"}),size:e.number().min(1,"Size is required").openapi({example:1024,description:"Size of the file in bytes"}),filename:e.string().min(1,"Filename is required").openapi({example:"example.png",description:"Name of the file"}),organizationId:e.string().optional().openapi({example:"clm1234567890abcdef",description:"ID of the organization"})}),FileSchema=e.object({id:e.string().min(1,"ID is required").openapi({example:"clf9876543210abcdef",description:"ID of the file"}),url:e.string().min(1,"Path is required").openapi({example:"/path/to/file",description:"Path of the file"}),mimeType:e.string().min(1,"MIME type is required").openapi({example:"image/png",description:"MIME type of the file"}),size:e.number().min(1,"Size is required").openapi({example:1024,description:"Size of the file in bytes"}),filename:e.string().min(1,"Filename is required").openapi({example:"example.png",description:"Name of the file"})}).openapi("UploadedFile");