@shophost/rest-api 2.0.33 → 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,139 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { createApiRoute } from "../../core/hono/hono";
3
- import { CreateProductCategorySchema, ErrorSchema, HeaderSchema, LocalizedProductCategorySchema, OrganizationParams, OrganizationWithIdParams, PaginationMetaSchema, PaginationQuerySchema, ProductCategorySchema, UpdateProductCategorySchema, } from "../../schemas";
4
- import { GetResourceQuerySchema } from "../../schemas/queries.schema";
5
- const getProductCategoriesRoute = createApiRoute({
6
- description: "Fetches a paginated list of product categories for a specific organization",
7
- headers: HeaderSchema,
8
- method: "GET",
9
- operationId: "getProductCategories",
10
- path: "/:organizationId/product-categories",
11
- pathParams: OrganizationParams,
12
- query: PaginationQuerySchema,
13
- responses: {
14
- 200: z.object({
15
- list: z.array(z.union([ProductCategorySchema, LocalizedProductCategorySchema])),
16
- meta: PaginationMetaSchema,
17
- }),
18
- 400: ErrorSchema,
19
- 401: ErrorSchema,
20
- },
21
- summary: "Get Product Categories",
22
- tags: ["ProductCategory"],
23
- });
24
- const createProductCategoryRoute = createApiRoute({
25
- body: CreateProductCategorySchema,
26
- description: "Creates a new product category for a specific organization",
27
- headers: HeaderSchema,
28
- method: "POST",
29
- operationId: "createProductCategory",
30
- path: "/:organizationId/product-categories",
31
- pathParams: OrganizationParams,
32
- responses: {
33
- 201: ProductCategorySchema,
34
- 400: ErrorSchema,
35
- 401: ErrorSchema,
36
- 404: ErrorSchema,
37
- },
38
- summary: "Create Product Category",
39
- tags: ["ProductCategory"],
40
- });
41
- const getProductCategoryRoute = createApiRoute({
42
- description: "Fetches a specific product category by ID",
43
- headers: HeaderSchema,
44
- method: "GET",
45
- operationId: "getProductCategory",
46
- path: "/:organizationId/product-categories/:id",
47
- pathParams: OrganizationWithIdParams,
48
- query: GetResourceQuerySchema,
49
- responses: {
50
- 200: z.union([ProductCategorySchema, LocalizedProductCategorySchema]),
51
- 401: ErrorSchema,
52
- 404: ErrorSchema,
53
- },
54
- summary: "Get Product Category",
55
- tags: ["ProductCategory"],
56
- });
57
- const updateProductCategoryRoute = createApiRoute({
58
- body: UpdateProductCategorySchema,
59
- description: "Updates a specific product category by ID",
60
- headers: HeaderSchema,
61
- method: "PATCH",
62
- operationId: "updateProductCategory",
63
- path: "/:organizationId/product-categories/:id",
64
- pathParams: OrganizationWithIdParams,
65
- responses: {
66
- 200: ProductCategorySchema,
67
- 400: ErrorSchema,
68
- 401: ErrorSchema,
69
- 404: ErrorSchema,
70
- },
71
- summary: "Update Product Category",
72
- tags: ["ProductCategory"],
73
- });
74
- const updateProductCategoryStatusRoute = createApiRoute({
75
- description: "Sets the published status of an existing product category based on the operation (publish or unpublish)",
76
- headers: HeaderSchema,
77
- method: "POST",
78
- operationId: "updateProductCategoryStatus",
79
- path: "/:organizationId/product-categories/:id/status/:operation",
80
- pathParams: z.object({
81
- id: z.string().openapi({
82
- description: "The organization ID",
83
- example: "ckel0e8qw00004n5p5w6fznym",
84
- param: {
85
- in: "path",
86
- name: "id",
87
- },
88
- }),
89
- operation: z.enum(["publish", "unpublish"]).openapi({
90
- description: "The operation to perform on the product category",
91
- example: "publish",
92
- param: {
93
- in: "path",
94
- name: "operation",
95
- },
96
- }),
97
- organizationId: z.string().openapi({
98
- description: "The organization ID",
99
- example: "ckel0e8qw00004n5p5w6fznym",
100
- param: {
101
- in: "path",
102
- name: "organizationId",
103
- },
104
- }),
105
- }),
106
- responses: {
107
- 200: ProductCategorySchema,
108
- 400: ErrorSchema,
109
- 401: ErrorSchema,
110
- 404: ErrorSchema,
111
- },
112
- summary: "Publish or Unpublish Product Category",
113
- tags: ["ProductCategory"],
114
- });
115
- const deleteProductCategoryRoute = createApiRoute({
116
- description: "Deletes a specific product category by ID",
117
- headers: HeaderSchema,
118
- method: "DELETE",
119
- operationId: "deleteProductCategory",
120
- path: "/:organizationId/product-categories/:id",
121
- pathParams: OrganizationWithIdParams,
122
- responses: {
123
- 204: null,
124
- 400: ErrorSchema,
125
- 401: ErrorSchema,
126
- 404: ErrorSchema,
127
- },
128
- summary: "Delete Product Category",
129
- tags: ["ProductCategory"],
130
- });
131
- export const productCategoryRoute = {
132
- getProductCategories: getProductCategoriesRoute,
133
- createProductCategory: createProductCategoryRoute,
134
- getProductCategory: getProductCategoryRoute,
135
- updateProductCategory: updateProductCategoryRoute,
136
- updateProductCategoryStatus: updateProductCategoryStatusRoute,
137
- deleteProductCategory: deleteProductCategoryRoute,
138
- };
139
- //# sourceMappingURL=product-category.route.js.map
1
+ import{z as e}from"@hono/zod-openapi";import{createApiRoute as o}from"../../core/hono/hono";import{CreateProductCategorySchema as s,ErrorSchema as t,HeaderSchema as a,LocalizedProductCategorySchema as d,OrganizationParams as c,OrganizationWithIdParams as i,PaginationMetaSchema as p,PaginationQuerySchema as n,ProductCategorySchema as r,UpdateProductCategorySchema as u}from"../../schemas";import{GetResourceQuerySchema as g}from"../../schemas/queries.schema";const m=o({description:"Fetches a paginated list of product categories for a specific organization",headers:a,method:"GET",operationId:"getProductCategories",path:"/:organizationId/product-categories",pathParams:c,query:n,responses:{200:e.object({list:e.array(e.union([r,d])),meta:p}),400:t,401:t},summary:"Get Product Categories",tags:["ProductCategory"]}),y=o({body:s,description:"Creates a new product category for a specific organization",headers:a,method:"POST",operationId:"createProductCategory",path:"/:organizationId/product-categories",pathParams:c,responses:{201:r,400:t,401:t,404:t},summary:"Create Product Category",tags:["ProductCategory"]}),h=o({description:"Fetches a specific product category by ID",headers:a,method:"GET",operationId:"getProductCategory",path:"/:organizationId/product-categories/:id",pathParams:i,query:g,responses:{200:e.union([r,d]),401:t,404:t},summary:"Get Product Category",tags:["ProductCategory"]}),P=o({body:u,description:"Updates a specific product category by ID",headers:a,method:"PATCH",operationId:"updateProductCategory",path:"/:organizationId/product-categories/:id",pathParams:i,responses:{200:r,400:t,401:t,404:t},summary:"Update Product Category",tags:["ProductCategory"]}),C=o({description:"Sets the published status of an existing product category based on the operation (publish or unpublish)",headers:a,method:"POST",operationId:"updateProductCategoryStatus",path:"/:organizationId/product-categories/:id/status/:operation",pathParams:e.object({id:e.string().openapi({description:"The organization ID",example:"ckel0e8qw00004n5p5w6fznym",param:{in:"path",name:"id"}}),operation:e.enum(["publish","unpublish"]).openapi({description:"The operation to perform on the product category",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 Category",tags:["ProductCategory"]}),l=o({description:"Deletes a specific product category by ID",headers:a,method:"DELETE",operationId:"deleteProductCategory",path:"/:organizationId/product-categories/:id",pathParams:i,responses:{204:null,400:t,401:t,404:t},summary:"Delete Product Category",tags:["ProductCategory"]});export const productCategoryRoute={getProductCategories:m,createProductCategory:y,getProductCategory:h,updateProductCategory:P,updateProductCategoryStatus:C,deleteProductCategory:l};
@@ -1,86 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { validateRequiredForDefaultLocale } from "../../core/utils/zod.util";
3
- import { FileSchema } from "../file/file.schema";
4
- export const ProductCategorySchema = z
5
- .object({
6
- id: z.string().openapi({
7
- example: "clf9876543210abcdef",
8
- description: "ID of the product category",
9
- }),
10
- slug: z.string().openapi({
11
- example: "electronics",
12
- description: "Slug of the product category",
13
- }),
14
- image: FileSchema.nullable().optional().openapi({
15
- description: "Image of the product category",
16
- }),
17
- createdAt: z.date(),
18
- publishedAt: z.date().nullable().optional().openapi({
19
- description: "Timestamp when the product category was published",
20
- }),
21
- translations: z
22
- .array(z.object({
23
- locale: z.string().min(1, "Locale is required").openapi({
24
- example: "en-US",
25
- description: "Locale code for the translation",
26
- }),
27
- title: z.string().default("").openapi({
28
- example: "Electronics",
29
- description: "Name of the product category in the specified locale",
30
- }),
31
- description: z
32
- .string()
33
- .max(6000, "Maximum character limit is 6000")
34
- .nullable()
35
- .default("")
36
- .optional()
37
- .openapi({
38
- example: "A category for electronic devices.",
39
- description: "Description of the product category in the specified locale",
40
- }),
41
- }))
42
- .openapi({
43
- description: "List of translations for the product category",
44
- }),
45
- })
46
- .openapi("ProductCategory");
47
- export const LocalizedProductCategorySchema = ProductCategorySchema.omit({
48
- translations: true,
49
- })
50
- .extend({
51
- title: z.string().default(""),
52
- description: z.string().default(""),
53
- })
54
- .openapi("LocalizedProductCategory");
55
- export const CreateProductCategorySchema = ProductCategorySchema.pick({
56
- slug: true,
57
- image: true,
58
- translations: true,
59
- })
60
- .extend({
61
- defaultLocale: z.string().min(1, "Default locale is required").openapi({
62
- description: "The default locale for the product category",
63
- }),
64
- imageId: z.string().cuid().optional().openapi({
65
- description: "ID of the image for the product category",
66
- }),
67
- })
68
- .superRefine(validateRequiredForDefaultLocale("title"))
69
- .openapi("CreateProductCategory");
70
- export const UpdateProductCategorySchema = ProductCategorySchema.pick({
71
- slug: true,
72
- image: true,
73
- translations: true,
74
- })
75
- .extend({
76
- defaultLocale: z.string().min(1, "Default locale is required").openapi({
77
- description: "The default locale for the product category",
78
- }),
79
- imageId: z.string().cuid().optional().nullable().openapi({
80
- description: "ID of the image for the product category",
81
- }),
82
- })
83
- .partial()
84
- .superRefine(validateRequiredForDefaultLocale("title"))
85
- .openapi("UpdateProductCategory");
86
- //# sourceMappingURL=product-category.schema.js.map
1
+ import{z as e}from"@hono/zod-openapi";import{validateRequiredForDefaultLocale as t}from"../../core/utils/zod.util";import{FileSchema as o}from"../file/file.schema";export const ProductCategorySchema=e.object({id:e.string().openapi({example:"clf9876543210abcdef",description:"ID of the product category"}),slug:e.string().openapi({example:"electronics",description:"Slug of the product category"}),image:o.nullable().optional().openapi({description:"Image of the product category"}),createdAt:e.date(),publishedAt:e.date().nullable().optional().openapi({description:"Timestamp when the product category was published"}),translations:e.array(e.object({locale:e.string().min(1,"Locale is required").openapi({example:"en-US",description:"Locale code for the translation"}),title:e.string().default("").openapi({example:"Electronics",description:"Name of the product category in the specified locale"}),description:e.string().max(6e3,"Maximum character limit is 6000").nullable().default("").optional().openapi({example:"A category for electronic devices.",description:"Description of the product category in the specified locale"})})).openapi({description:"List of translations for the product category"})}).openapi("ProductCategory"),LocalizedProductCategorySchema=ProductCategorySchema.omit({translations:!0}).extend({title:e.string().default(""),description:e.string().default("")}).openapi("LocalizedProductCategory"),CreateProductCategorySchema=ProductCategorySchema.pick({slug:!0,image:!0,translations:!0}).extend({defaultLocale:e.string().min(1,"Default locale is required").openapi({description:"The default locale for the product category"}),imageId:e.string().cuid().optional().openapi({description:"ID of the image for the product category"})}).superRefine(t("title")).openapi("CreateProductCategory"),UpdateProductCategorySchema=ProductCategorySchema.pick({slug:!0,image:!0,translations:!0}).extend({defaultLocale:e.string().min(1,"Default locale is required").openapi({description:"The default locale for the product category"}),imageId:e.string().cuid().optional().nullable().openapi({description:"ID of the image for the product category"})}).partial().superRefine(t("title")).openapi("UpdateProductCategory");
@@ -1,220 +1 @@
1
- import { __awaiter } from "tslib";
2
- import { z } from "@hono/zod-openapi";
3
- import { HttpException } from "../../core/exceptions/http-exception";
4
- import { flattenTranslationData } from "../../core/utils/zod.util";
5
- import { LocalizedProductCategorySchema, PaginationMetaSchema, ProductCategorySchema, } from "../../schemas";
6
- class ProductCategoryService {
7
- constructor(prisma) {
8
- this.prisma = prisma;
9
- }
10
- /**
11
- * Find a product category by ID and organization ID
12
- * @throws HttpException with 404 status if product category is not found
13
- */
14
- findProductCategory(id, organizationId, options) {
15
- return __awaiter(this, void 0, void 0, function* () {
16
- const productCategory = yield this.prisma.productCategory.findUnique({
17
- where: {
18
- id,
19
- organizationId,
20
- deletedAt: null,
21
- },
22
- include: options === null || options === void 0 ? void 0 : options.include,
23
- });
24
- if (!productCategory) {
25
- throw new HttpException(404, "Product category not found");
26
- }
27
- return productCategory;
28
- });
29
- }
30
- /**
31
- * Create a new product category
32
- */
33
- createProductCategory(organizationId, userId, body) {
34
- return __awaiter(this, void 0, void 0, function* () {
35
- // Create new product category
36
- const productCategory = yield this.prisma.productCategory.create({
37
- data: {
38
- slug: body.slug,
39
- organizationId,
40
- createdBy: userId,
41
- imageId: body.imageId,
42
- translations: {
43
- create: body.translations,
44
- },
45
- },
46
- include: {
47
- translations: true,
48
- image: true,
49
- },
50
- });
51
- return ProductCategorySchema.parse(productCategory);
52
- });
53
- }
54
- /**
55
- * Get a product category by ID
56
- */
57
- getProductCategory(organizationId, id, query) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- // Extract locale from query parameter
60
- const { locale } = query;
61
- const productCategory = yield this.findProductCategory(id, organizationId, {
62
- include: {
63
- image: true,
64
- translations: locale
65
- ? {
66
- where: { locale },
67
- }
68
- : true,
69
- },
70
- });
71
- if (!locale) {
72
- return ProductCategorySchema.parse(productCategory);
73
- }
74
- // If locale is provided, flatten the translations data and use LocalizedProductCategorySchema
75
- return LocalizedProductCategorySchema.parse(flattenTranslationData(productCategory));
76
- });
77
- }
78
- /**
79
- * Get a paginated list of product categories
80
- */
81
- getProductCategories(organizationId, query) {
82
- return __awaiter(this, void 0, void 0, function* () {
83
- const { page = 1, limit = 10, search, locale, published } = query;
84
- // Fetch product categories with pagination
85
- const [list, meta] = yield this.prisma.productCategory
86
- .paginate({
87
- orderBy: {
88
- priority: "asc",
89
- },
90
- where: Object.assign(Object.assign({ organizationId, deletedAt: null }, (search && {
91
- slug: {
92
- contains: search,
93
- mode: "insensitive",
94
- },
95
- })), (published && {
96
- publishedAt: {
97
- not: null,
98
- },
99
- })),
100
- include: {
101
- image: true,
102
- translations: locale
103
- ? {
104
- where: { locale },
105
- }
106
- : true,
107
- },
108
- })
109
- .withPages({
110
- page,
111
- limit,
112
- });
113
- if (!locale) {
114
- // Return standard response with ProductCategorySchema
115
- return z
116
- .object({
117
- meta: PaginationMetaSchema,
118
- list: z.array(ProductCategorySchema),
119
- })
120
- .parse({
121
- meta,
122
- list,
123
- });
124
- }
125
- // Process the list for localization
126
- const localizedList = list.map((item) => flattenTranslationData(item));
127
- // Return localized response with LocalizedProductCategorySchema
128
- return z
129
- .object({
130
- meta: PaginationMetaSchema,
131
- list: z.array(LocalizedProductCategorySchema),
132
- })
133
- .parse({
134
- meta,
135
- list: localizedList,
136
- });
137
- });
138
- }
139
- /**
140
- * Update a product category
141
- */
142
- updateProductCategory(organizationId, id, userId, body) {
143
- return __awaiter(this, void 0, void 0, function* () {
144
- // Fetch product category by id
145
- yield this.findProductCategory(id, organizationId);
146
- // Update product category
147
- const updatedProductCategory = yield this.prisma.productCategory.update({
148
- where: {
149
- id,
150
- organizationId,
151
- deletedAt: null,
152
- },
153
- data: {
154
- updatedBy: userId,
155
- slug: body.slug,
156
- translations: {
157
- deleteMany: {},
158
- create: body.translations || [],
159
- },
160
- imageId: body.imageId,
161
- },
162
- include: {
163
- image: true,
164
- translations: true,
165
- },
166
- });
167
- return ProductCategorySchema.parse(updatedProductCategory);
168
- });
169
- }
170
- /**
171
- * Update product category status (publish/unpublish)
172
- */
173
- updateProductCategoryStatus(organizationId, id, operation, userId) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- // Fetch the product category by id
176
- yield this.findProductCategory(id, organizationId);
177
- const updatedProductCategory = yield this.prisma.productCategory.update({
178
- where: {
179
- id,
180
- organizationId,
181
- deletedAt: null,
182
- },
183
- data: {
184
- publishedAt: operation === "publish" ? new Date() : null,
185
- publishedBy: operation === "publish" ? userId : null,
186
- updatedBy: userId,
187
- },
188
- include: {
189
- image: true,
190
- translations: true,
191
- },
192
- });
193
- return ProductCategorySchema.parse(updatedProductCategory);
194
- });
195
- }
196
- /**
197
- * Delete a product category (soft delete)
198
- */
199
- deleteProductCategory(organizationId, id, userId) {
200
- return __awaiter(this, void 0, void 0, function* () {
201
- // Fetch product category by id
202
- yield this.findProductCategory(id, organizationId);
203
- // Soft delete product category
204
- yield this.prisma.productCategory.update({
205
- where: {
206
- id,
207
- organizationId,
208
- deletedAt: null,
209
- },
210
- data: {
211
- deletedAt: new Date(),
212
- deletedBy: userId,
213
- },
214
- });
215
- return;
216
- });
217
- }
218
- }
219
- export { ProductCategoryService };
220
- //# sourceMappingURL=product-category.service.js.map
1
+ import{__awaiter as o}from"tslib";import{z as u}from"@hono/zod-openapi";import{HttpException as C}from"../../core/exceptions/http-exception";import{flattenTranslationData as c}from"../../core/utils/zod.util";import{LocalizedProductCategorySchema as p,PaginationMetaSchema as g,ProductCategorySchema as d}from"../../schemas";class f{constructor(t){this.prisma=t}findProductCategory(t,a,e){return o(this,void 0,void 0,function*(){const r=yield this.prisma.productCategory.findUnique({where:{id:t,organizationId:a,deletedAt:null},include:e?.include});if(!r)throw new C(404,"Product category not found");return r})}createProductCategory(t,a,e){return o(this,void 0,void 0,function*(){const r=yield this.prisma.productCategory.create({data:{slug:e.slug,organizationId:t,createdBy:a,imageId:e.imageId,translations:{create:e.translations}},include:{translations:!0,image:!0}});return d.parse(r)})}getProductCategory(t,a,e){return o(this,void 0,void 0,function*(){const{locale:r}=e,i=yield this.findProductCategory(a,t,{include:{image:!0,translations:r?{where:{locale:r}}:!0}});return r?p.parse(c(i)):d.parse(i)})}getProductCategories(t,a){return o(this,void 0,void 0,function*(){const{page:e=1,limit:r=10,search:i,locale:n,published:y}=a,[s,l]=yield this.prisma.productCategory.paginate({orderBy:{priority:"asc"},where:Object.assign(Object.assign({organizationId:t,deletedAt:null},i&&{slug:{contains:i,mode:"insensitive"}}),y&&{publishedAt:{not:null}}),include:{image:!0,translations:n?{where:{locale:n}}:!0}}).withPages({page:e,limit:r});if(!n)return u.object({meta:g,list:u.array(d)}).parse({meta:l,list:s});const h=s.map(m=>c(m));return u.object({meta:g,list:u.array(p)}).parse({meta:l,list:h})})}updateProductCategory(t,a,e,r){return o(this,void 0,void 0,function*(){yield this.findProductCategory(a,t);const i=yield this.prisma.productCategory.update({where:{id:a,organizationId:t,deletedAt:null},data:{updatedBy:e,slug:r.slug,translations:{deleteMany:{},create:r.translations||[]},imageId:r.imageId},include:{image:!0,translations:!0}});return d.parse(i)})}updateProductCategoryStatus(t,a,e,r){return o(this,void 0,void 0,function*(){yield this.findProductCategory(a,t);const i=yield this.prisma.productCategory.update({where:{id:a,organizationId:t,deletedAt:null},data:{publishedAt:e==="publish"?new Date:null,publishedBy:e==="publish"?r:null,updatedBy:r},include:{image:!0,translations:!0}});return d.parse(i)})}deleteProductCategory(t,a,e){return o(this,void 0,void 0,function*(){yield this.findProductCategory(a,t),yield this.prisma.productCategory.update({where:{id:a,organizationId:t,deletedAt:null},data:{deletedAt:new Date,deletedBy:e}})})}}export{f as ProductCategoryService};
@@ -1,82 +1 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Body, Column, Container, Head, Heading, Hr, Html, Img, Link, Preview, Row, Section, Tailwind, Text, } from "@react-email/components";
3
- import { format } from "date-fns";
4
- const ReservationCancellationEmail = ({ user, organization, reservation, }) => {
5
- var _a, _b, _c, _d, _e;
6
- const previewText = `Your reservation with ${organization.name} has been cancelled`;
7
- const formattedDate = format(new Date(reservation.date), "dd.MM.yyyy 'at' HH:mm");
8
- return (_jsxs(Html, { children: [_jsx(Head, {}), _jsx(Preview, { children: previewText }), _jsx(Tailwind, { children: _jsxs(Body, { className: "bg-gray-50 font-sans", children: [_jsxs(Container, { className: "bg-gray-50 p-6 max-w-[600px]", children: [_jsx(Section, { className: "mb-6", children: _jsxs(Row, { children: [_jsx(Column, { className: "w-[80%]", children: _jsx(Img, { alt: `${organization.name} logo`, height: "100", src: (_a = organization.logoFile) === null || _a === void 0 ? void 0 : _a.url, className: "rounded-lg" }) }), _jsx(Column, { align: "right", children: _jsxs(Row, { align: "right", children: [_jsx(Column, { children: _jsx(Link, { href: "https://www.instagram.com/madrasbistro/", children: _jsx(Img, { alt: "Instagram", className: "mx-[4px]", height: "36", src: "https://react.email/static/instagram-logo.png", width: "36" }) }) }), _jsx(Column, { children: _jsx(Link, { href: "https://www.facebook.com/madrasBistro/", children: _jsx(Img, { alt: "Facebook", className: "mx-[4px]", height: "36", src: "https://react.email/static/facebook-logo.png", width: "36" }) }) })] }) })] }) }), _jsxs(Section, { children: [_jsxs(Heading, { className: "text-3xl font-bold text-gray-800 mb-0", children: ["Hi ", user.firstname, ","] }), _jsx(Text, { className: "text-gray-600 mb-2 text-lg", children: "Your reservation has been cancelled." })] })] }), _jsxs(Container, { className: "mx-auto max-w-[600px] rounded-xl bg-white px-6", children: [_jsx(Section, { className: "mb-6", children: _jsxs(Row, { children: [_jsxs(Column, { className: "w-[60%]", children: [_jsx(Text, { className: "text-gray-500 mb-0", children: "Cancelled reservation details" }), _jsxs(Text, { className: "font-semibold text-gray-800 my-0", children: [reservation.firstname, " ", reservation.lastname] }), _jsxs(Text, { className: "font-semibold text-gray-800 my-0", children: ["Reference: ", reservation.referenceId] }), _jsxs(Text, { className: "font-semibold text-gray-800 my-0", children: ["Date and Time: ", formattedDate] }), _jsxs(Text, { className: "font-semibold text-gray-800 my-0", children: ["Number of Guests: ", reservation.guests] })] }), _jsx(Column, { className: "w-[40%] p-0 mt-0", align: "right", valign: "top", children: _jsx(Text, { className: "text-gray-500 mb-0 pt-1", children: format(new Date(), "dd.MM.yyyy") }) })] }) }), _jsx(Hr, { className: "border-gray-200 mt-4" }), _jsxs(Section, { className: "mb-6", children: [_jsxs(Text, { className: "text-gray-700", children: ["Your reservation at ", organization.name, " has been cancelled. If you did not request this cancellation or wish to make a new reservation, please contact us at ", organization.phone, "."] }), _jsxs(Text, { className: "text-gray-700", children: ["We hope to welcome you at ", organization.name, " another time."] })] })] }), _jsx(Section, { className: "text-center bg-gray-50 py-5", children: _jsxs("table", { className: "w-full", children: [_jsx("tr", { className: "w-full", children: _jsx("td", { align: "center", children: ((_b = organization.logoFile) === null || _b === void 0 ? void 0 : _b.url) && (_jsx(Img, { alt: `${organization.name} logo`, height: "100", src: organization.logoFile.url, className: "rounded-lg" })) }) }), _jsx("tr", { className: "w-full", children: _jsxs("td", { align: "center", children: [_jsx(Text, { className: "my-[8px] text-[16px] font-semibold text-xl pt-2 text-gray-900", children: organization.name }), _jsxs(Text, { className: "my-[8px] text-[16px] leading-[24px] text-gray-500", children: [(_c = organization.address) === null || _c === void 0 ? void 0 : _c.addressLineOne, ",", " ", (_d = organization.address) === null || _d === void 0 ? void 0 : _d.zipCode, " ", (_e = organization.address) === null || _e === void 0 ? void 0 : _e.city] }), _jsx(Text, { className: "mb-0 mt-[4px] text-[16px] leading-[24px] text-gray-500", children: organization.phone })] }) }), _jsx("tr", { children: _jsx("td", { align: "center", children: _jsxs(Row, { className: "table-cell h-[44px] w-[56px] align-bottom pt-5", children: [_jsx(Column, { className: "pr-[8px]", children: _jsx(Link, { href: "https://www.facebook.com/madrasBistro/", children: _jsx(Img, { alt: "Facebook", height: "36", src: "https://react.email/static/facebook-logo.png", width: "36" }) }) }), _jsx(Column, { children: _jsx(Link, { href: "https://www.instagram.com/madrasbistro/", children: _jsx(Img, { alt: "Instagram", height: "36", src: "https://react.email/static/instagram-logo.png", width: "36" }) }) })] }) }) })] }) })] }) })] }));
9
- };
10
- const previewProps = {
11
- user: {
12
- id: "VD0OJ52f0mdAnm5YePP6BAW6hdbaCjAJ",
13
- name: "Abhishek Shaji",
14
- email: "kontakt@abhishek.pl",
15
- emailVerified: true,
16
- image: "https://lh3.googleusercontent.com/a/ACg8ocKbkCAMTNvMizjXNxcm1aYtBiWnYpCYmU-7aE2Ft_M_uiHheZ5f=s96-c",
17
- createdAt: "2025-03-22T22:54:40.260Z",
18
- updatedAt: "2025-03-22T22:54:40.260Z",
19
- firstname: "Abhishek",
20
- lastname: "Shaji",
21
- },
22
- reservation: {
23
- id: "cm94wbpbm0000itx1iv9k2mqr",
24
- referenceId: "PH6LD6",
25
- firstname: "Abhishek",
26
- lastname: "Shaji",
27
- phone: "+48570135862",
28
- guests: 4,
29
- date: new Date("2025-04-07T19:30:00.000Z"),
30
- createdAt: "2025-03-22T22:54:40.260Z",
31
- acceptedAt: "2025-03-22T23:00:23.456Z",
32
- cancelledAt: "2025-03-23T10:15:45.789Z",
33
- },
34
- organization: {
35
- id: "cm8kthfdq0001lg03b59mdy7b",
36
- name: "Madras Bistro",
37
- phone: "+48570135862",
38
- email: "contact@madrasbistro.pl",
39
- createdAt: "2025-03-22T23:05:14.271Z",
40
- legalEntityId: null,
41
- address: {
42
- id: "cm8kthfdr0002lg0350ijialt",
43
- firstname: null,
44
- lastname: null,
45
- phone: null,
46
- addressLineOne: "Plac Bohaterów Getta 2",
47
- doorNumber: null,
48
- addressLineTwo: "3",
49
- zipCode: "33-332",
50
- city: "Kraków",
51
- country: "PL",
52
- placeId: "ChIJf-nsRkRbFkcR21gtObFSSSA",
53
- deliveryInstructions: null,
54
- },
55
- configuration: {
56
- id: "cm8kthfdr0003lg03ghgs262n",
57
- hostname: "madrasbistro.pl",
58
- countriesShipping: ["us"],
59
- stripeAccountId: "null",
60
- enableHostCheckout: false,
61
- enableHostTracking: false,
62
- isAcceptingOrders: false,
63
- defaultLocale: "en",
64
- supportedLocales: ["en", "pl"],
65
- defaultCurrency: "PLN",
66
- createdAt: "2025-03-22T23:05:14.271Z",
67
- },
68
- logo: "https://z3liuyatqnepss3d.public.blob.vercel-storage.com/logo-zeJymFRMFCIKPlvjxYm2af3SAWvBOj.png",
69
- logoFile: {
70
- id: "cm8ktmu890005lg0356gwclfk",
71
- url: "https://z3liuyatqnepss3d.public.blob.vercel-storage.com/logo-zeJymFRMFCIKPlvjxYm2af3SAWvBOj.png",
72
- mimeType: "image/png",
73
- size: 1652289,
74
- filename: "logo.png",
75
- },
76
- },
77
- };
78
- // Fixed the TypeScript error by using proper type assertion
79
- ReservationCancellationEmail.PreviewProps = previewProps;
80
- export default ReservationCancellationEmail;
81
- export { ReservationCancellationEmail };
82
- //# sourceMappingURL=reservation-cancellation.email.js.map
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Body as N,Column as s,Container as b,Head as v,Heading as k,Hr as A,Html as T,Img as r,Link as n,Preview as C,Row as d,Section as i,Tailwind as j,Text as l}from"@react-email/components";import{format as x}from"date-fns";const u=({user:f,organization:t,reservation:c})=>{var m,o,h,g,p;const y=`Your reservation with ${t.name} has been cancelled`,w=x(new Date(c.date),"dd.MM.yyyy 'at' HH:mm");return a(T,{children:[e(v,{}),e(C,{children:y}),e(j,{children:a(N,{className:"bg-gray-50 font-sans",children:[a(b,{className:"bg-gray-50 p-6 max-w-[600px]",children:[e(i,{className:"mb-6",children:a(d,{children:[e(s,{className:"w-[80%]",children:e(r,{alt:`${t.name} logo`,height:"100",src:(m=t.logoFile)===null||m===void 0?void 0:m.url,className:"rounded-lg"})}),e(s,{align:"right",children:a(d,{align:"right",children:[e(s,{children:e(n,{href:"https://www.instagram.com/madrasbistro/",children:e(r,{alt:"Instagram",className:"mx-[4px]",height:"36",src:"https://react.email/static/instagram-logo.png",width:"36"})})}),e(s,{children:e(n,{href:"https://www.facebook.com/madrasBistro/",children:e(r,{alt:"Facebook",className:"mx-[4px]",height:"36",src:"https://react.email/static/facebook-logo.png",width:"36"})})})]})})]})}),a(i,{children:[a(k,{className:"text-3xl font-bold text-gray-800 mb-0",children:["Hi ",f.firstname,","]}),e(l,{className:"text-gray-600 mb-2 text-lg",children:"Your reservation has been cancelled."})]})]}),a(b,{className:"mx-auto max-w-[600px] rounded-xl bg-white px-6",children:[e(i,{className:"mb-6",children:a(d,{children:[a(s,{className:"w-[60%]",children:[e(l,{className:"text-gray-500 mb-0",children:"Cancelled reservation details"}),a(l,{className:"font-semibold text-gray-800 my-0",children:[c.firstname," ",c.lastname]}),a(l,{className:"font-semibold text-gray-800 my-0",children:["Reference: ",c.referenceId]}),a(l,{className:"font-semibold text-gray-800 my-0",children:["Date and Time: ",w]}),a(l,{className:"font-semibold text-gray-800 my-0",children:["Number of Guests: ",c.guests]})]}),e(s,{className:"w-[40%] p-0 mt-0",align:"right",valign:"top",children:e(l,{className:"text-gray-500 mb-0 pt-1",children:x(new Date,"dd.MM.yyyy")})})]})}),e(A,{className:"border-gray-200 mt-4"}),a(i,{className:"mb-6",children:[a(l,{className:"text-gray-700",children:["Your reservation at ",t.name," has been cancelled. If you did not request this cancellation or wish to make a new reservation, please contact us at ",t.phone,"."]}),a(l,{className:"text-gray-700",children:["We hope to welcome you at ",t.name," another time."]})]})]}),e(i,{className:"text-center bg-gray-50 py-5",children:a("table",{className:"w-full",children:[e("tr",{className:"w-full",children:e("td",{align:"center",children:((o=t.logoFile)===null||o===void 0?void 0:o.url)&&e(r,{alt:`${t.name} logo`,height:"100",src:t.logoFile.url,className:"rounded-lg"})})}),e("tr",{className:"w-full",children:a("td",{align:"center",children:[e(l,{className:"my-[8px] text-[16px] font-semibold text-xl pt-2 text-gray-900",children:t.name}),a(l,{className:"my-[8px] text-[16px] leading-[24px] text-gray-500",children:[(h=t.address)===null||h===void 0?void 0:h.addressLineOne,","," ",(g=t.address)===null||g===void 0?void 0:g.zipCode," ",(p=t.address)===null||p===void 0?void 0:p.city]}),e(l,{className:"mb-0 mt-[4px] text-[16px] leading-[24px] text-gray-500",children:t.phone})]})}),e("tr",{children:e("td",{align:"center",children:a(d,{className:"table-cell h-[44px] w-[56px] align-bottom pt-5",children:[e(s,{className:"pr-[8px]",children:e(n,{href:"https://www.facebook.com/madrasBistro/",children:e(r,{alt:"Facebook",height:"36",src:"https://react.email/static/facebook-logo.png",width:"36"})})}),e(s,{children:e(n,{href:"https://www.instagram.com/madrasbistro/",children:e(r,{alt:"Instagram",height:"36",src:"https://react.email/static/instagram-logo.png",width:"36"})})})]})})})]})})]})})]})},F={user:{id:"VD0OJ52f0mdAnm5YePP6BAW6hdbaCjAJ",name:"Abhishek Shaji",email:"kontakt@abhishek.pl",emailVerified:!0,image:"https://lh3.googleusercontent.com/a/ACg8ocKbkCAMTNvMizjXNxcm1aYtBiWnYpCYmU-7aE2Ft_M_uiHheZ5f=s96-c",createdAt:"2025-03-22T22:54:40.260Z",updatedAt:"2025-03-22T22:54:40.260Z",firstname:"Abhishek",lastname:"Shaji"},reservation:{id:"cm94wbpbm0000itx1iv9k2mqr",referenceId:"PH6LD6",firstname:"Abhishek",lastname:"Shaji",phone:"+48570135862",guests:4,date:new Date("2025-04-07T19:30:00.000Z"),createdAt:"2025-03-22T22:54:40.260Z",acceptedAt:"2025-03-22T23:00:23.456Z",cancelledAt:"2025-03-23T10:15:45.789Z"},organization:{id:"cm8kthfdq0001lg03b59mdy7b",name:"Madras Bistro",phone:"+48570135862",email:"contact@madrasbistro.pl",createdAt:"2025-03-22T23:05:14.271Z",legalEntityId:null,address:{id:"cm8kthfdr0002lg0350ijialt",firstname:null,lastname:null,phone:null,addressLineOne:"Plac Bohater\xF3w Getta 2",doorNumber:null,addressLineTwo:"3",zipCode:"33-332",city:"Krak\xF3w",country:"PL",placeId:"ChIJf-nsRkRbFkcR21gtObFSSSA",deliveryInstructions:null},configuration:{id:"cm8kthfdr0003lg03ghgs262n",hostname:"madrasbistro.pl",countriesShipping:["us"],stripeAccountId:"null",enableHostCheckout:!1,enableHostTracking:!1,isAcceptingOrders:!1,defaultLocale:"en",supportedLocales:["en","pl"],defaultCurrency:"PLN",createdAt:"2025-03-22T23:05:14.271Z"},logo:"https://z3liuyatqnepss3d.public.blob.vercel-storage.com/logo-zeJymFRMFCIKPlvjxYm2af3SAWvBOj.png",logoFile:{id:"cm8ktmu890005lg0356gwclfk",url:"https://z3liuyatqnepss3d.public.blob.vercel-storage.com/logo-zeJymFRMFCIKPlvjxYm2af3SAWvBOj.png",mimeType:"image/png",size:1652289,filename:"logo.png"}}};u.PreviewProps=F;export default u;export{u as ReservationCancellationEmail};