@shophost/rest-api 2.0.34 → 2.0.35

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 (148) hide show
  1. package/package.json +1 -1
  2. package/scripts/minify-dist.mjs +45 -0
  3. package/src/app.js +1 -53
  4. package/src/core/auth/auth.schema.js +1 -41
  5. package/src/core/auth/auth.util.js +1 -44
  6. package/src/core/auth/better-auth.lib.js +1 -100
  7. package/src/core/auth/generate-password-hash.util.js +1 -30
  8. package/src/core/auth/headers.schema.js +1 -22
  9. package/src/core/auth/user.schema.js +1 -30
  10. package/src/core/db/__generated__/client/browser.js +1 -18
  11. package/src/core/db/__generated__/client/client.js +1 -35
  12. package/src/core/db/__generated__/client/commonInputTypes.js +1 -11
  13. package/src/core/db/__generated__/client/enums.js +1 -200
  14. package/src/core/db/__generated__/client/internal/class.js +769 -55
  15. package/src/core/db/__generated__/client/internal/prismaNamespace.js +1 -541
  16. package/src/core/db/__generated__/client/internal/prismaNamespaceBrowser.js +1 -512
  17. package/src/core/db/__generated__/client/models/Account.js +1 -2
  18. package/src/core/db/__generated__/client/models/Address.js +1 -2
  19. package/src/core/db/__generated__/client/models/Campaign.js +1 -2
  20. package/src/core/db/__generated__/client/models/ClosingTimes.js +1 -2
  21. package/src/core/db/__generated__/client/models/File.js +1 -2
  22. package/src/core/db/__generated__/client/models/Invitation.js +1 -2
  23. package/src/core/db/__generated__/client/models/LegalEntity.js +1 -2
  24. package/src/core/db/__generated__/client/models/Manufacturer.js +1 -2
  25. package/src/core/db/__generated__/client/models/ManufacturerTranslation.js +1 -2
  26. package/src/core/db/__generated__/client/models/Member.js +1 -2
  27. package/src/core/db/__generated__/client/models/Modifier.js +1 -2
  28. package/src/core/db/__generated__/client/models/ModifierGroup.js +1 -2
  29. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.js +1 -2
  30. package/src/core/db/__generated__/client/models/OpeningTimes.js +1 -2
  31. package/src/core/db/__generated__/client/models/Order.js +1 -2
  32. package/src/core/db/__generated__/client/models/OrderItem.js +1 -2
  33. package/src/core/db/__generated__/client/models/OrderItemTranslation.js +1 -2
  34. package/src/core/db/__generated__/client/models/Organization.js +1 -2
  35. package/src/core/db/__generated__/client/models/OrganizationConfiguration.js +1 -2
  36. package/src/core/db/__generated__/client/models/Payment.js +1 -2
  37. package/src/core/db/__generated__/client/models/PaymentSession.js +1 -2
  38. package/src/core/db/__generated__/client/models/Product.js +1 -2
  39. package/src/core/db/__generated__/client/models/ProductCategory.js +1 -2
  40. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.js +1 -2
  41. package/src/core/db/__generated__/client/models/ProductSnapshot.js +1 -2
  42. package/src/core/db/__generated__/client/models/ProductTranslation.js +1 -2
  43. package/src/core/db/__generated__/client/models/Reservation.js +1 -2
  44. package/src/core/db/__generated__/client/models/Session.js +1 -2
  45. package/src/core/db/__generated__/client/models/ShippingMethod.js +1 -2
  46. package/src/core/db/__generated__/client/models/ShippingZone.js +1 -2
  47. package/src/core/db/__generated__/client/models/User.js +1 -2
  48. package/src/core/db/__generated__/client/models/Verification.js +1 -2
  49. package/src/core/db/__generated__/client/models.js +1 -2
  50. package/src/core/db/index.js +1 -2
  51. package/src/core/exceptions/http-exception.js +1 -9
  52. package/src/core/hono/hono.js +1 -123
  53. package/src/core/lib/prisma.js +1 -11
  54. package/src/core/logging/pino.js +1 -5
  55. package/src/core/notifications/email.service.js +1 -116
  56. package/src/core/openapi/openapi.lib.js +1 -26
  57. package/src/core/types/google-maps.types.js +1 -2
  58. package/src/core/utils/currency.util.js +1 -11
  59. package/src/core/utils/env.util.js +1 -8
  60. package/src/core/utils/object.util.js +1 -39
  61. package/src/core/utils/translations.util.js +0 -1
  62. package/src/core/utils/zod.util.js +1 -85
  63. package/src/db.js +1 -3
  64. package/src/features/access/access.handler.js +1 -91
  65. package/src/features/access/access.route.js +1 -220
  66. package/src/features/access/access.schema.js +1 -108
  67. package/src/features/access/access.service.js +1 -294
  68. package/src/features/cart/cart.handler.js +1 -17
  69. package/src/features/cart/cart.route.js +1 -32
  70. package/src/features/cart/cart.schema.js +1 -39
  71. package/src/features/cart/cart.service.js +1 -97
  72. package/src/features/cart/cart.util.js +1 -76
  73. package/src/features/file/file.handler.js +1 -23
  74. package/src/features/file/file.route.js +1 -34
  75. package/src/features/file/file.schema.js +1 -77
  76. package/src/features/file/file.service.js +1 -66
  77. package/src/features/health/health.handler.js +1 -10
  78. package/src/features/health/health.route.js +1 -25
  79. package/src/features/index.js +1 -16
  80. package/src/features/location/location.handler.js +1 -25
  81. package/src/features/location/location.route.js +1 -56
  82. package/src/features/location/location.schema.js +1 -50
  83. package/src/features/location/location.service.js +1 -141
  84. package/src/features/manufacturer/manufacturer.handler.js +1 -53
  85. package/src/features/manufacturer/manufacturer.route.js +1 -97
  86. package/src/features/manufacturer/manufacturer.schema.js +1 -125
  87. package/src/features/manufacturer/manufacturer.service.js +1 -190
  88. package/src/features/order/emails/order-confirmation.email.js +1 -229
  89. package/src/features/order/emails/order-notification.email.js +1 -229
  90. package/src/features/order/fulfilment.schema.js +1 -3
  91. package/src/features/order/order.handler.js +1 -54
  92. package/src/features/order/order.route.js +1 -111
  93. package/src/features/order/order.schema.js +1 -158
  94. package/src/features/order/order.service.js +1 -306
  95. package/src/features/order/recipient.schema.js +1 -38
  96. package/src/features/organization/legal-entity.schema.js +1 -83
  97. package/src/features/organization/organization-configuration.schema.js +1 -115
  98. package/src/features/organization/organization.handler.js +1 -48
  99. package/src/features/organization/organization.route.js +1 -84
  100. package/src/features/organization/organization.schema.js +1 -64
  101. package/src/features/organization/organization.service.js +1 -334
  102. package/src/features/payment/payment.handler.js +1 -16
  103. package/src/features/payment/payment.route.js +1 -22
  104. package/src/features/payment/payment.schema.js +1 -46
  105. package/src/features/payment/payment.service.js +1 -100
  106. package/src/features/payment/stripe.service.js +1 -164
  107. package/src/features/product/product-modifier.schema.js +1 -84
  108. package/src/features/product/product.handler.js +1 -87
  109. package/src/features/product/product.route.js +1 -179
  110. package/src/features/product/product.schema.js +1 -143
  111. package/src/features/product/product.service.js +1 -440
  112. package/src/features/product-category/product-category.handler.js +1 -59
  113. package/src/features/product-category/product-category.route.js +1 -139
  114. package/src/features/product-category/product-category.schema.js +1 -86
  115. package/src/features/product-category/product-category.service.js +1 -220
  116. package/src/features/reservation/emails/reservation-cancellation.email.js +1 -82
  117. package/src/features/reservation/emails/reservation-confirmation.email.js +1 -82
  118. package/src/features/reservation/emails/reservation-notification.email.js +1 -93
  119. package/src/features/reservation/reservation.handler.js +1 -65
  120. package/src/features/reservation/reservation.route.js +1 -167
  121. package/src/features/reservation/reservation.schema.js +1 -51
  122. package/src/features/reservation/reservation.service.js +1 -231
  123. package/src/features/shipping/shipping.handler.js +1 -32
  124. package/src/features/shipping/shipping.route.js +1 -51
  125. package/src/features/shipping/shipping.service.js +1 -96
  126. package/src/features/shipping-method/shipping-method.handler.js +1 -60
  127. package/src/features/shipping-method/shipping-method.route.js +1 -144
  128. package/src/features/shipping-method/shipping-method.schema.js +1 -48
  129. package/src/features/shipping-method/shipping-method.service.js +1 -229
  130. package/src/features/shipping-method/shipping-zone.schema.js +1 -31
  131. package/src/features/webhook/webhook.handler.js +1 -50
  132. package/src/features/webhook/webhook.route.js +1 -33
  133. package/src/index.js +1 -6
  134. package/src/integrations/next.js +1 -82
  135. package/src/schemas/address.schema.js +1 -112
  136. package/src/schemas/currency.schema.js +1 -118
  137. package/src/schemas/error.schema.js +1 -12
  138. package/src/schemas/index.js +1 -29
  139. package/src/schemas/locales.schema.js +1 -238
  140. package/src/schemas/number.schema.js +1 -29
  141. package/src/schemas/pagination.schema.js +1 -54
  142. package/src/schemas/params.schema.js +1 -20
  143. package/src/schemas/queries.schema.js +1 -6
  144. package/src/test/global-setup.js +1 -37
  145. package/src/test/integration/api-fixtures.js +1 -160
  146. package/src/test/integration/seed.js +1 -368
  147. package/src/test/integration/test-helpers.js +1 -154
  148. package/src/test/setup-test-env.js +1 -7
@@ -1,100 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { HttpException } from "../../core/exceptions/http-exception";
3
- import { StripeService } from "./stripe.service";
4
- class PaymentService {
5
- constructor(prisma, options) {
6
- this.prisma = prisma;
7
- this.options = options;
8
- if (!(options === null || options === void 0 ? void 0 : options.stripe)) {
9
- throw new Error("Stripe options must be provided");
10
- }
11
- this.stripeService = new StripeService(prisma, options.stripe);
12
- }
13
- getPaymentMethods() {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- const methods = [];
16
- if (this.options.stripe &&
17
- this.options.stripe.paymentMethods.includes("card")) {
18
- methods.push({
19
- id: "stripe:card",
20
- provider: "stripe",
21
- description: "Visa, Mastercard, American Express etc..",
22
- method: "card",
23
- });
24
- }
25
- if (this.options.stripe &&
26
- this.options.stripe.paymentMethods.includes("blik")) {
27
- methods.push({
28
- id: "stripe:blik",
29
- provider: "stripe",
30
- description: "Popular payment method in Poland",
31
- method: "blik",
32
- });
33
- }
34
- if (this.options.revolut &&
35
- this.options.revolut.paymentMethods.includes("card")) {
36
- methods.push({
37
- id: "revolut:card",
38
- provider: "revolut",
39
- description: "Visa, Mastercard, American Express etc..",
40
- method: "card",
41
- });
42
- }
43
- if (this.options.revolut &&
44
- this.options.revolut.paymentMethods.includes("blik")) {
45
- methods.push({
46
- id: "revolut:blik",
47
- provider: "revolut",
48
- description: "Popular payment method in Poland",
49
- method: "blik",
50
- });
51
- }
52
- return methods;
53
- });
54
- }
55
- handleCheckoutSessionByProvider(user, order, options) {
56
- switch (order.payment.provider) {
57
- case "stripe":
58
- return this.stripeService.createCheckoutSession(user, order, options);
59
- default:
60
- throw new HttpException(400, "Payment provider not supported");
61
- }
62
- }
63
- createCheckoutSession(user, order, options) {
64
- return __awaiter(this, void 0, void 0, function* () {
65
- const session = yield this.handleCheckoutSessionByProvider(user, order, options);
66
- yield this.prisma.paymentSession.create({
67
- data: {
68
- payment: {
69
- connect: {
70
- id: order.payment.id,
71
- },
72
- },
73
- referenceId: session.id,
74
- amount: order.payment.total,
75
- currency: order.payment.currency,
76
- rawData: JSON.stringify(session),
77
- },
78
- });
79
- return {
80
- sessionId: session.id,
81
- redirectUrl: session.url,
82
- };
83
- });
84
- }
85
- processWebhookEvent(provider, signature, body) {
86
- return __awaiter(this, void 0, void 0, function* () {
87
- if (!signature) {
88
- throw new HttpException(401, "Signature is required");
89
- }
90
- switch (provider) {
91
- case "stripe":
92
- return this.stripeService.handleWebhookEvent(signature, body);
93
- default:
94
- throw new HttpException(400, "Payment provider not supported");
95
- }
96
- });
97
- }
98
- }
99
- export { PaymentService };
100
- //# sourceMappingURL=payment.service.js.map
1
+ import{__awaiter as o}from"tslib";import{HttpException as s}from"../../core/exceptions/http-exception";import{StripeService as n}from"./stripe.service";class d{constructor(t,e){if(this.prisma=t,this.options=e,!e?.stripe)throw new Error("Stripe options must be provided");this.stripeService=new n(t,e.stripe)}getPaymentMethods(){return o(this,void 0,void 0,function*(){const t=[];return this.options.stripe&&this.options.stripe.paymentMethods.includes("card")&&t.push({id:"stripe:card",provider:"stripe",description:"Visa, Mastercard, American Express etc..",method:"card"}),this.options.stripe&&this.options.stripe.paymentMethods.includes("blik")&&t.push({id:"stripe:blik",provider:"stripe",description:"Popular payment method in Poland",method:"blik"}),this.options.revolut&&this.options.revolut.paymentMethods.includes("card")&&t.push({id:"revolut:card",provider:"revolut",description:"Visa, Mastercard, American Express etc..",method:"card"}),this.options.revolut&&this.options.revolut.paymentMethods.includes("blik")&&t.push({id:"revolut:blik",provider:"revolut",description:"Popular payment method in Poland",method:"blik"}),t})}handleCheckoutSessionByProvider(t,e,i){if(e.payment.provider==="stripe")return this.stripeService.createCheckoutSession(t,e,i);throw new s(400,"Payment provider not supported")}createCheckoutSession(t,e,i){return o(this,void 0,void 0,function*(){const r=yield this.handleCheckoutSessionByProvider(t,e,i);return yield this.prisma.paymentSession.create({data:{payment:{connect:{id:e.payment.id}},referenceId:r.id,amount:e.payment.total,currency:e.payment.currency,rawData:JSON.stringify(r)}}),{sessionId:r.id,redirectUrl:r.url}})}processWebhookEvent(t,e,i){return o(this,void 0,void 0,function*(){if(!e)throw new s(401,"Signature is required");if(t==="stripe")return this.stripeService.handleWebhookEvent(e,i);throw new s(400,"Payment provider not supported")})}}export{d as PaymentService};
@@ -1,164 +1 @@
1
- import { __awaiter } from "tslib";
2
- import Stripe from "stripe";
3
- import { HttpException } from "../../core/exceptions/http-exception";
4
- import { EmailService } from "../../core/notifications/email.service";
5
- import { OrderSchema, OrganizationSchema, UserSchema, } from "../../schemas";
6
- class StripeService {
7
- constructor(prisma, options) {
8
- this.prisma = prisma;
9
- this.options = options;
10
- if (options === null || options === void 0 ? void 0 : options.secretKey) {
11
- this.stripe = new Stripe(options.secretKey);
12
- }
13
- if (options === null || options === void 0 ? void 0 : options.resendApiKey) {
14
- this.emailService = new EmailService(options.resendApiKey);
15
- }
16
- }
17
- handleCheckoutSessionCompleted(event) {
18
- return __awaiter(this, void 0, void 0, function* () {
19
- var _a, _b, _c;
20
- const session = event.data.object;
21
- const paymentSession = yield this.prisma.paymentSession.findFirst({
22
- where: {
23
- referenceId: session.id,
24
- },
25
- });
26
- if (!paymentSession) {
27
- throw new HttpException(404, "Payment session not found");
28
- }
29
- yield this.prisma.paymentSession.update({
30
- where: {
31
- id: paymentSession.id,
32
- },
33
- data: {
34
- capturedAt: new Date(),
35
- payment: {
36
- update: {
37
- status: "succeeded",
38
- },
39
- },
40
- },
41
- });
42
- if (!((_a = session.metadata) === null || _a === void 0 ? void 0 : _a.orderId) || !this.emailService) {
43
- return;
44
- }
45
- const order = yield this.prisma.order.findFirst({
46
- where: {
47
- id: (_b = session.metadata) === null || _b === void 0 ? void 0 : _b.orderId,
48
- },
49
- include: {
50
- items: {
51
- include: {
52
- translations: true,
53
- image: true,
54
- },
55
- },
56
- payment: true,
57
- organization: {
58
- include: {
59
- address: true,
60
- configuration: true,
61
- logoFile: true,
62
- members: {
63
- include: {
64
- user: true,
65
- },
66
- },
67
- },
68
- },
69
- shippingAddress: true,
70
- shippingMethod: {
71
- include: {
72
- shippingZones: true,
73
- },
74
- },
75
- },
76
- });
77
- const user = yield this.prisma.user.findFirst({
78
- where: {
79
- id: (_c = session.metadata) === null || _c === void 0 ? void 0 : _c.userId,
80
- },
81
- });
82
- if (!order || !user) {
83
- return;
84
- }
85
- yield this.emailService.sendOrderConfirmationEmail(UserSchema.parse(user), OrganizationSchema.parse(order.organization), OrderSchema.parse(order));
86
- for (const member of order.organization.members) {
87
- yield this.emailService.sendOrderNotificationEmail(UserSchema.parse(user), UserSchema.parse(member.user), OrganizationSchema.parse(order.organization), OrderSchema.parse(order));
88
- }
89
- });
90
- }
91
- createCheckoutSession(user_1, order_1, _a) {
92
- return __awaiter(this, arguments, void 0, function* (user, order, { locale, successUrl, cancelUrl }) {
93
- var _b;
94
- if (!this.stripe) {
95
- throw new Error("Stripe is not configured");
96
- }
97
- if (order.payment.method !== "card" && order.payment.method !== "blik") {
98
- throw new Error("Payment method not supported");
99
- }
100
- const params = {
101
- payment_method_types: [order.payment.method],
102
- customer_email: user.email,
103
- line_items: order.items.map(({ translations, unitPrice, quantity, image }) => {
104
- var _a;
105
- const translation = translations.find((t) => t.locale === locale);
106
- return {
107
- quantity,
108
- price_data: {
109
- currency: "pln",
110
- product_data: {
111
- name: (_a = translation === null || translation === void 0 ? void 0 : translation.title) !== null && _a !== void 0 ? _a : "N/A",
112
- description: (translation === null || translation === void 0 ? void 0 : translation.subtitle) || undefined,
113
- images: (image === null || image === void 0 ? void 0 : image.url) ? [image === null || image === void 0 ? void 0 : image.url] : undefined,
114
- },
115
- unit_amount: unitPrice * 100,
116
- },
117
- };
118
- }),
119
- shipping_options: ((_b = order.shippingMethod) === null || _b === void 0 ? void 0 : _b.shippingZones[0].price)
120
- ? [
121
- {
122
- shipping_rate_data: {
123
- type: "fixed_amount",
124
- fixed_amount: {
125
- amount: order.payment.shipping * 100,
126
- currency: order.currency.toLowerCase(),
127
- },
128
- display_name: "Delivery fee",
129
- },
130
- },
131
- ]
132
- : undefined,
133
- mode: "payment",
134
- success_url: successUrl,
135
- cancel_url: cancelUrl,
136
- metadata: {
137
- userId: user.id,
138
- orderId: order.id,
139
- },
140
- };
141
- return this.stripe.checkout.sessions.create(params);
142
- });
143
- }
144
- handleWebhookEvent(signature, body) {
145
- return __awaiter(this, void 0, void 0, function* () {
146
- var _a;
147
- if (!this.stripe) {
148
- throw new Error("Stripe is not configured");
149
- }
150
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.webhookSecret)) {
151
- throw new Error("Stripe webhook secret is not configured");
152
- }
153
- const event = this.stripe.webhooks.constructEvent(body, signature, this.options.webhookSecret);
154
- switch (event.type) {
155
- case "checkout.session.completed":
156
- return this.handleCheckoutSessionCompleted(event);
157
- default:
158
- throw new Error(`Unhandled event type ${event.type}`);
159
- }
160
- });
161
- }
162
- }
163
- export { StripeService };
164
- //# sourceMappingURL=stripe.service.js.map
1
+ import{__awaiter as l}from"tslib";import g from"stripe";import{HttpException as b}from"../../core/exceptions/http-exception";import{EmailService as k}from"../../core/notifications/email.service";import{OrderSchema as h,OrganizationSchema as v,UserSchema as m}from"../../schemas";class E{constructor(o,e){this.prisma=o,this.options=e,e?.secretKey&&(this.stripe=new g(e.secretKey)),e?.resendApiKey&&(this.emailService=new k(e.resendApiKey))}handleCheckoutSessionCompleted(o){return l(this,void 0,void 0,function*(){var e,r,t;const i=o.data.object,c=yield this.prisma.paymentSession.findFirst({where:{referenceId:i.id}});if(!c)throw new b(404,"Payment session not found");if(yield this.prisma.paymentSession.update({where:{id:c.id},data:{capturedAt:new Date,payment:{update:{status:"succeeded"}}}}),!(!((e=i.metadata)===null||e===void 0)&&e.orderId)||!this.emailService)return;const n=yield this.prisma.order.findFirst({where:{id:(r=i.metadata)===null||r===void 0?void 0:r.orderId},include:{items:{include:{translations:!0,image:!0}},payment:!0,organization:{include:{address:!0,configuration:!0,logoFile:!0,members:{include:{user:!0}}}},shippingAddress:!0,shippingMethod:{include:{shippingZones:!0}}}}),d=yield this.prisma.user.findFirst({where:{id:(t=i.metadata)===null||t===void 0?void 0:t.userId}});if(!(!n||!d)){yield this.emailService.sendOrderConfirmationEmail(m.parse(d),v.parse(n.organization),h.parse(n));for(const u of n.organization.members)yield this.emailService.sendOrderNotificationEmail(m.parse(d),m.parse(u.user),v.parse(n.organization),h.parse(n))}})}createCheckoutSession(o,e,r){return l(this,arguments,void 0,function*(t,i,{locale:c,successUrl:n,cancelUrl:d}){var u;if(!this.stripe)throw new Error("Stripe is not configured");if(i.payment.method!=="card"&&i.payment.method!=="blik")throw new Error("Payment method not supported");const f={payment_method_types:[i.payment.method],customer_email:t.email,line_items:i.items.map(({translations:y,unitPrice:w,quantity:_,image:s})=>{var p;const a=y.find(S=>S.locale===c);return{quantity:_,price_data:{currency:"pln",product_data:{name:(p=a?.title)!==null&&p!==void 0?p:"N/A",description:a?.subtitle||void 0,images:s?.url?[s?.url]:void 0},unit_amount:w*100}}}),shipping_options:!((u=i.shippingMethod)===null||u===void 0)&&u.shippingZones[0].price?[{shipping_rate_data:{type:"fixed_amount",fixed_amount:{amount:i.payment.shipping*100,currency:i.currency.toLowerCase()},display_name:"Delivery fee"}}]:void 0,mode:"payment",success_url:n,cancel_url:d,metadata:{userId:t.id,orderId:i.id}};return this.stripe.checkout.sessions.create(f)})}handleWebhookEvent(o,e){return l(this,void 0,void 0,function*(){var r;if(!this.stripe)throw new Error("Stripe is not configured");if(!(!((r=this.options)===null||r===void 0)&&r.webhookSecret))throw new Error("Stripe webhook secret is not configured");const t=this.stripe.webhooks.constructEvent(e,o,this.options.webhookSecret);if(t.type==="checkout.session.completed")return this.handleCheckoutSessionCompleted(t);throw new Error(`Unhandled event type ${t.type}`)})}}export{E as StripeService};
@@ -1,84 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { validateRequiredForDefaultLocale } from "../../core/utils/zod.util";
3
- import { locale } from "../../schemas/locales.schema";
4
- export const ModifierSchema = z
5
- .object({
6
- id: z.string().cuid().optional(),
7
- title: z.string().min(1, "This field is required").openapi({
8
- example: "Large",
9
- description: "Title of the modifier",
10
- }),
11
- sku: z.coerce.string().optional().openapi({
12
- example: "csd9876543210abcdef",
13
- description: "Stock Keeping Unit identifier",
14
- }),
15
- price: z.coerce.number().optional().default(0).openapi({
16
- example: 2.5,
17
- description: "Price of the modifier",
18
- }),
19
- })
20
- .openapi("Modifier");
21
- export const ModifierGroupSchema = z
22
- .object({
23
- id: z.string().cuid(),
24
- selectMin: z.coerce.number().min(0).openapi({
25
- example: 1,
26
- description: "Minimum number of modifiers that can be selected",
27
- }),
28
- selectMax: z.coerce.number().min(0).openapi({
29
- example: 1,
30
- description: "Maximum number of modifiers that can be selected",
31
- }),
32
- defaultLocale: locale.optional(),
33
- modifiers: z.array(ModifierSchema).optional().openapi({}),
34
- translations: z.array(z.object({
35
- locale,
36
- title: z.string().optional().openapi({
37
- example: "Size",
38
- description: "Title of the modifier group",
39
- }),
40
- })),
41
- })
42
- .openapi("ModifierGroup");
43
- export const LocalizedModifierGroupSchema = ModifierGroupSchema.extend({
44
- title: z.string().default("").nullable(),
45
- })
46
- .omit({
47
- translations: true,
48
- })
49
- .openapi("LocalizedModifierGroup");
50
- export const CreateOrUpdateModifierGroupSchema = z
51
- .object({
52
- selectMin: z.coerce.number().min(0).openapi({
53
- example: 1,
54
- description: "Minimum number of modifiers that can be selected",
55
- }),
56
- selectMax: z.coerce.number().min(0).openapi({
57
- example: 1,
58
- description: "Maximum number of modifiers that can be selected",
59
- }),
60
- defaultLocale: locale.optional(),
61
- modifiers: z.array(ModifierSchema).optional().openapi({}),
62
- translations: z.array(z.object({
63
- locale,
64
- title: z.string().optional().openapi({
65
- example: "Size",
66
- description: "Title of the modifier group",
67
- }),
68
- })),
69
- })
70
- .refine((data) => data.selectMax >= data.selectMin, {
71
- message: "Maximum selections must be greater than or equal to minimum selections",
72
- path: ["selectMax"],
73
- })
74
- .refine((data) => {
75
- var _a;
76
- const modifierCount = ((_a = data.modifiers) === null || _a === void 0 ? void 0 : _a.length) || 0;
77
- return data.selectMax <= modifierCount;
78
- }, {
79
- message: "Maximum selections cannot exceed the total number of modifiers",
80
- path: ["selectMax"],
81
- })
82
- .superRefine(validateRequiredForDefaultLocale("title"))
83
- .openapi("ModifierGroup");
84
- //# sourceMappingURL=product-modifier.schema.js.map
1
+ import{z as e}from"@hono/zod-openapi";import{validateRequiredForDefaultLocale as a}from"../../core/utils/zod.util";import{locale as o}from"../../schemas/locales.schema";export const ModifierSchema=e.object({id:e.string().cuid().optional(),title:e.string().min(1,"This field is required").openapi({example:"Large",description:"Title of the modifier"}),sku:e.coerce.string().optional().openapi({example:"csd9876543210abcdef",description:"Stock Keeping Unit identifier"}),price:e.coerce.number().optional().default(0).openapi({example:2.5,description:"Price of the modifier"})}).openapi("Modifier"),ModifierGroupSchema=e.object({id:e.string().cuid(),selectMin:e.coerce.number().min(0).openapi({example:1,description:"Minimum number of modifiers that can be selected"}),selectMax:e.coerce.number().min(0).openapi({example:1,description:"Maximum number of modifiers that can be selected"}),defaultLocale:o.optional(),modifiers:e.array(ModifierSchema).optional().openapi({}),translations:e.array(e.object({locale:o,title:e.string().optional().openapi({example:"Size",description:"Title of the modifier group"})}))}).openapi("ModifierGroup"),LocalizedModifierGroupSchema=ModifierGroupSchema.extend({title:e.string().default("").nullable()}).omit({translations:!0}).openapi("LocalizedModifierGroup"),CreateOrUpdateModifierGroupSchema=e.object({selectMin:e.coerce.number().min(0).openapi({example:1,description:"Minimum number of modifiers that can be selected"}),selectMax:e.coerce.number().min(0).openapi({example:1,description:"Maximum number of modifiers that can be selected"}),defaultLocale:o.optional(),modifiers:e.array(ModifierSchema).optional().openapi({}),translations:e.array(e.object({locale:o,title:e.string().optional().openapi({example:"Size",description:"Title of the modifier group"})}))}).refine(i=>i.selectMax>=i.selectMin,{message:"Maximum selections must be greater than or equal to minimum selections",path:["selectMax"]}).refine(i=>{var t;const r=((t=i.modifiers)===null||t===void 0?void 0:t.length)||0;return i.selectMax<=r},{message:"Maximum selections cannot exceed the total number of modifiers",path:["selectMax"]}).superRefine(a("title")).openapi("ModifierGroup");
@@ -1,87 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { createApiRouter } from "../../core/hono/hono";
3
- import { productRoute } from "./product.route";
4
- import { ProductService } from "./product.service";
5
- export const buildProductHandler = (prisma) => {
6
- const app = createApiRouter();
7
- app.openapi(productRoute.createProduct, (c) => __awaiter(void 0, void 0, void 0, function* () {
8
- const auth = c.get("auth");
9
- const params = c.req.valid("param");
10
- const body = c.req.valid("json");
11
- const user = yield auth.isGranted("create");
12
- const service = new ProductService(prisma);
13
- const product = yield service.createProduct(params.organizationId, user.id, body);
14
- return c.json(product, 201);
15
- }));
16
- app.openapi(productRoute.getProduct, (c) => __awaiter(void 0, void 0, void 0, function* () {
17
- const auth = c.get("auth");
18
- const params = c.req.valid("param");
19
- const query = c.req.valid("query");
20
- let hasPrivateAccess = false;
21
- try {
22
- yield auth.isGranted("read");
23
- hasPrivateAccess = true;
24
- }
25
- catch (error) {
26
- console.log("User only has public access");
27
- }
28
- const service = new ProductService(prisma);
29
- const product = yield service.getProduct(params.organizationId, params.id, {
30
- locale: query.locale || null,
31
- published: !hasPrivateAccess,
32
- });
33
- return c.json(product, 200);
34
- }));
35
- app.openapi(productRoute.getProducts, (c) => __awaiter(void 0, void 0, void 0, function* () {
36
- const auth = c.get("auth");
37
- const params = c.req.valid("param");
38
- const query = c.req.valid("query");
39
- let hasPrivateAccess = false;
40
- try {
41
- yield auth.isGranted("read");
42
- hasPrivateAccess = true;
43
- }
44
- catch (error) {
45
- console.log("User only has public access");
46
- }
47
- const service = new ProductService(prisma);
48
- const result = yield service.getProducts(params.organizationId, Object.assign(Object.assign({}, query), { locale: query.locale || null, published: !hasPrivateAccess }));
49
- return c.json(result, 200);
50
- }));
51
- app.openapi(productRoute.updateProduct, (c) => __awaiter(void 0, void 0, void 0, function* () {
52
- const auth = c.get("auth");
53
- const params = c.req.valid("param");
54
- const body = c.req.valid("json");
55
- const user = yield auth.isGranted("update");
56
- const service = new ProductService(prisma);
57
- const updatedProduct = yield service.updateProduct(params.organizationId, params.id, user.id, body);
58
- return c.json(updatedProduct, 200);
59
- }));
60
- app.openapi(productRoute.updateProductStatus, (c) => __awaiter(void 0, void 0, void 0, function* () {
61
- const auth = c.get("auth");
62
- const params = c.req.valid("param");
63
- const user = yield auth.isGranted("update");
64
- const service = new ProductService(prisma);
65
- const updatedProduct = yield service.updateProductStatus(params.organizationId, params.id, params.operation, user.id);
66
- return c.json(updatedProduct, 200);
67
- }));
68
- app.openapi(productRoute.deleteProduct, (c) => __awaiter(void 0, void 0, void 0, function* () {
69
- const auth = c.get("auth");
70
- const params = c.req.valid("param");
71
- const user = yield auth.isGranted("delete");
72
- const service = new ProductService(prisma);
73
- yield service.deleteProduct(params.organizationId, params.id, user.id);
74
- return c.body(null, 204);
75
- }));
76
- app.openapi(productRoute.getProductsByCategory, (c) => __awaiter(void 0, void 0, void 0, function* () {
77
- const auth = c.get("auth");
78
- const params = c.req.valid("param");
79
- const query = c.req.valid("query");
80
- yield auth.isGranted("read");
81
- const service = new ProductService(prisma);
82
- const result = yield service.getProductsByCategory(params.organizationId, params.categoryId, Object.assign(Object.assign({}, query), { locale: query.locale || null }));
83
- return c.json(result, 200);
84
- }));
85
- return app;
86
- };
87
- //# sourceMappingURL=product.handler.js.map
1
+ import{__awaiter as c}from"tslib";import{createApiRouter as p}from"../../core/hono/hono";import{productRoute as u}from"./product.route";import{ProductService as l}from"./product.service";export const buildProductHandler=n=>{const i=p();return i.openapi(u.createProduct,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=e.req.valid("json"),a=yield r.isGranted("create"),s=yield new l(n).createProduct(t.organizationId,a.id,o);return e.json(s,201)})),i.openapi(u.getProduct,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=e.req.valid("query");let a=!1;try{yield r.isGranted("read"),a=!0}catch{console.log("User only has public access")}const s=yield new l(n).getProduct(t.organizationId,t.id,{locale:o.locale||null,published:!a});return e.json(s,200)})),i.openapi(u.getProducts,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=e.req.valid("query");let a=!1;try{yield r.isGranted("read"),a=!0}catch{console.log("User only has public access")}const s=yield new l(n).getProducts(t.organizationId,Object.assign(Object.assign({},o),{locale:o.locale||null,published:!a}));return e.json(s,200)})),i.openapi(u.updateProduct,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=e.req.valid("json"),a=yield r.isGranted("update"),s=yield new l(n).updateProduct(t.organizationId,t.id,a.id,o);return e.json(s,200)})),i.openapi(u.updateProductStatus,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=yield r.isGranted("update"),d=yield new l(n).updateProductStatus(t.organizationId,t.id,t.operation,o.id);return e.json(d,200)})),i.openapi(u.deleteProduct,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=yield r.isGranted("delete");return yield new l(n).deleteProduct(t.organizationId,t.id,o.id),e.body(null,204)})),i.openapi(u.getProductsByCategory,e=>c(void 0,void 0,void 0,function*(){const r=e.get("auth"),t=e.req.valid("param"),o=e.req.valid("query");yield r.isGranted("read");const d=yield new l(n).getProductsByCategory(t.organizationId,t.categoryId,Object.assign(Object.assign({},o),{locale:o.locale||null}));return e.json(d,200)})),i};
@@ -1,179 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { createApiRoute } from "../../core/hono/hono";
3
- import { CreateProductSchema, ErrorSchema, HeaderSchema, LocalizedProductSchema, OrganizationParams, OrganizationWithIdParams, PaginationMetaSchema, PaginationQuerySchema, ProductSchema, UpdateProductSchema, } from "../../schemas";
4
- import { GetResourceQuerySchema } from "../../schemas/queries.schema";
5
- const OrganizationWithCategoryParams = z
6
- .object({
7
- categoryId: z.string().openapi({
8
- description: "The category ID",
9
- example: "ckel0e8qw00004n5p5w6fznym",
10
- param: {
11
- in: "path",
12
- name: "categoryId",
13
- },
14
- }),
15
- organizationId: z.string().openapi({
16
- description: "The organization ID",
17
- example: "ckel0e8qw00004n5p5w6fznym",
18
- param: {
19
- in: "path",
20
- name: "organizationId",
21
- },
22
- }),
23
- })
24
- .openapi("OrganizationWithCategoryParams");
25
- const getProductsRoute = createApiRoute({
26
- description: "Fetches paginated list of products",
27
- headers: HeaderSchema,
28
- method: "GET",
29
- operationId: "getProducts",
30
- path: "/:organizationId/products",
31
- pathParams: OrganizationParams,
32
- query: PaginationQuerySchema,
33
- responses: {
34
- 200: z.object({
35
- list: z.array(z.union([ProductSchema, LocalizedProductSchema])),
36
- meta: PaginationMetaSchema,
37
- }),
38
- 400: ErrorSchema,
39
- 401: ErrorSchema,
40
- },
41
- summary: "Get Products",
42
- tags: ["Product"],
43
- });
44
- const getProductRoute = createApiRoute({
45
- description: "Fetches a specific product by ID",
46
- headers: HeaderSchema,
47
- method: "GET",
48
- operationId: "getProduct",
49
- path: "/:organizationId/products/:id",
50
- pathParams: OrganizationWithIdParams,
51
- query: GetResourceQuerySchema,
52
- responses: {
53
- 200: z.union([ProductSchema, LocalizedProductSchema]),
54
- 401: ErrorSchema,
55
- 404: ErrorSchema,
56
- },
57
- summary: "Get Product",
58
- tags: ["Product"],
59
- });
60
- const updateProductRoute = createApiRoute({
61
- body: UpdateProductSchema,
62
- description: "Updates a specific product by ID",
63
- headers: HeaderSchema,
64
- method: "PATCH",
65
- operationId: "updateProduct",
66
- path: "/:organizationId/products/:id",
67
- pathParams: OrganizationWithIdParams,
68
- responses: {
69
- 200: ProductSchema,
70
- 400: ErrorSchema,
71
- 401: ErrorSchema,
72
- 404: ErrorSchema,
73
- },
74
- summary: "Update Product",
75
- tags: ["Product"],
76
- });
77
- const createProductRoute = createApiRoute({
78
- body: CreateProductSchema,
79
- description: "Creates a new product",
80
- headers: HeaderSchema,
81
- method: "POST",
82
- operationId: "createProduct",
83
- path: "/:organizationId/products",
84
- pathParams: OrganizationParams,
85
- responses: {
86
- 201: ProductSchema,
87
- 400: ErrorSchema,
88
- 401: ErrorSchema,
89
- 404: ErrorSchema,
90
- },
91
- summary: "Create Product",
92
- tags: ["Product"],
93
- });
94
- const updateProductStatusRoute = createApiRoute({
95
- description: "Sets the published status of an existing product based on the operation (publish or unpublish)",
96
- headers: HeaderSchema,
97
- method: "POST",
98
- operationId: "updateProductStatus",
99
- path: "/:organizationId/products/:id/status/:operation",
100
- pathParams: z.object({
101
- id: z.string().openapi({
102
- description: "The product ID",
103
- example: "ckel0e8qw00004n5p5w6fznym",
104
- param: {
105
- in: "path",
106
- name: "id",
107
- },
108
- }),
109
- operation: z.enum(["publish", "unpublish"]).openapi({
110
- description: "The operation to perform on the product",
111
- example: "publish",
112
- param: {
113
- in: "path",
114
- name: "operation",
115
- },
116
- }),
117
- organizationId: z.string().openapi({
118
- description: "The organization ID",
119
- example: "ckel0e8qw00004n5p5w6fznym",
120
- param: {
121
- in: "path",
122
- name: "organizationId",
123
- },
124
- }),
125
- }),
126
- responses: {
127
- 200: ProductSchema,
128
- 400: ErrorSchema,
129
- 401: ErrorSchema,
130
- 404: ErrorSchema,
131
- },
132
- summary: "Publish or Unpublish Product",
133
- tags: ["Product"],
134
- });
135
- const deleteProductRoute = createApiRoute({
136
- description: "Deletes a specific product by ID",
137
- headers: HeaderSchema,
138
- method: "DELETE",
139
- operationId: "deleteProduct",
140
- path: "/:organizationId/products/:id",
141
- pathParams: OrganizationWithIdParams,
142
- responses: {
143
- 204: null,
144
- 400: ErrorSchema,
145
- 401: ErrorSchema,
146
- 404: ErrorSchema,
147
- },
148
- summary: "Delete Product",
149
- tags: ["Product"],
150
- });
151
- const getProductsByCategoryRoute = createApiRoute({
152
- description: "Fetches a paginated list of products for a specific category",
153
- headers: HeaderSchema,
154
- method: "GET",
155
- operationId: "getProductsByCategory",
156
- path: "/:organizationId/products/by-category/:categoryId",
157
- pathParams: OrganizationWithCategoryParams,
158
- query: PaginationQuerySchema,
159
- responses: {
160
- 200: z.object({
161
- list: z.array(ProductSchema),
162
- meta: PaginationMetaSchema,
163
- }),
164
- 400: ErrorSchema,
165
- 401: ErrorSchema,
166
- },
167
- summary: "Get Products by Category",
168
- tags: ["Product"],
169
- });
170
- export const productRoute = {
171
- getProducts: getProductsRoute,
172
- getProduct: getProductRoute,
173
- updateProduct: updateProductRoute,
174
- createProduct: createProductRoute,
175
- updateProductStatus: updateProductStatusRoute,
176
- deleteProduct: deleteProductRoute,
177
- getProductsByCategory: getProductsByCategoryRoute,
178
- };
179
- //# sourceMappingURL=product.route.js.map
1
+ import{z as e}from"@hono/zod-openapi";import{createApiRoute as o}from"../../core/hono/hono";import{CreateProductSchema as c,ErrorSchema as t,HeaderSchema as a,LocalizedProductSchema as i,OrganizationParams as s,OrganizationWithIdParams as d,PaginationMetaSchema as n,PaginationQuerySchema as p,ProductSchema as r,UpdateProductSchema as u}from"../../schemas";import{GetResourceQuerySchema as m}from"../../schemas/queries.schema";const h=e.object({categoryId:e.string().openapi({description:"The category ID",example:"ckel0e8qw00004n5p5w6fznym",param:{in:"path",name:"categoryId"}}),organizationId:e.string().openapi({description:"The organization ID",example:"ckel0e8qw00004n5p5w6fznym",param:{in:"path",name:"organizationId"}})}).openapi("OrganizationWithCategoryParams"),P=o({description:"Fetches paginated list of products",headers:a,method:"GET",operationId:"getProducts",path:"/:organizationId/products",pathParams:s,query:p,responses:{200:e.object({list:e.array(e.union([r,i])),meta:n}),400:t,401:t},summary:"Get Products",tags:["Product"]}),g=o({description:"Fetches a specific product by ID",headers:a,method:"GET",operationId:"getProduct",path:"/:organizationId/products/:id",pathParams:d,query:m,responses:{200:e.union([r,i]),401:t,404:t},summary:"Get Product",tags:["Product"]}),y=o({body:u,description:"Updates a specific product by ID",headers:a,method:"PATCH",operationId:"updateProduct",path:"/:organizationId/products/:id",pathParams:d,responses:{200:r,400:t,401:t,404:t},summary:"Update Product",tags:["Product"]}),l=o({body:c,description:"Creates a new product",headers:a,method:"POST",operationId:"createProduct",path:"/:organizationId/products",pathParams:s,responses:{201:r,400:t,401:t,404:t},summary:"Create Product",tags:["Product"]}),I=o({description:"Sets the published status of an existing product based on the operation (publish or unpublish)",headers:a,method:"POST",operationId:"updateProductStatus",path:"/:organizationId/products/:id/status/:operation",pathParams:e.object({id:e.string().openapi({description:"The product ID",example:"ckel0e8qw00004n5p5w6fznym",param:{in:"path",name:"id"}}),operation:e.enum(["publish","unpublish"]).openapi({description:"The operation to perform on the product",example:"publish",param:{in:"path",name:"operation"}}),organizationId:e.string().openapi({description:"The organization ID",example:"ckel0e8qw00004n5p5w6fznym",param:{in:"path",name:"organizationId"}})}),responses:{200:r,400:t,401:t,404:t},summary:"Publish or Unpublish Product",tags:["Product"]}),z=o({description:"Deletes a specific product by ID",headers:a,method:"DELETE",operationId:"deleteProduct",path:"/:organizationId/products/:id",pathParams:d,responses:{204:null,400:t,401:t,404:t},summary:"Delete Product",tags:["Product"]}),b=o({description:"Fetches a paginated list of products for a specific category",headers:a,method:"GET",operationId:"getProductsByCategory",path:"/:organizationId/products/by-category/:categoryId",pathParams:h,query:p,responses:{200:e.object({list:e.array(r),meta:n}),400:t,401:t},summary:"Get Products by Category",tags:["Product"]});export const productRoute={getProducts:P,getProduct:g,updateProduct:y,createProduct:l,updateProductStatus:I,deleteProduct:z,getProductsByCategory:b};