@zyacreatives/shared 2.5.3 → 2.5.6

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.
@@ -298,6 +298,8 @@ export declare const UserWithPostsEntitySchema: z.ZodObject<{
298
298
  readonly JOB: "JOB";
299
299
  readonly POST: "POST";
300
300
  readonly PRODUCT: "PRODUCT";
301
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
302
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
301
303
  readonly COMMENT: "COMMENT";
302
304
  readonly JOB_APPLICATION: "JOB_APPLICATION";
303
305
  }>>;
@@ -349,6 +351,8 @@ export declare const UserWithPostsEntitySchema: z.ZodObject<{
349
351
  readonly JOB: "JOB";
350
352
  readonly POST: "POST";
351
353
  readonly PRODUCT: "PRODUCT";
354
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
355
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
352
356
  readonly COMMENT: "COMMENT";
353
357
  readonly JOB_APPLICATION: "JOB_APPLICATION";
354
358
  }>>;
@@ -373,6 +377,8 @@ export declare const UserWithProjectLikesEntitySchema: z.ZodObject<{
373
377
  readonly JOB: "JOB";
374
378
  readonly POST: "POST";
375
379
  readonly PRODUCT: "PRODUCT";
380
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
381
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
376
382
  readonly COMMENT: "COMMENT";
377
383
  readonly JOB_APPLICATION: "JOB_APPLICATION";
378
384
  }>;
@@ -400,6 +406,8 @@ export declare const UserWithPostLikesEntitySchema: z.ZodObject<{
400
406
  readonly JOB: "JOB";
401
407
  readonly POST: "POST";
402
408
  readonly PRODUCT: "PRODUCT";
409
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
410
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
403
411
  readonly COMMENT: "COMMENT";
404
412
  readonly JOB_APPLICATION: "JOB_APPLICATION";
405
413
  }>;
@@ -428,6 +436,8 @@ export declare const UserWithJobBookmarksEntitySchema: z.ZodObject<{
428
436
  readonly JOB: "JOB";
429
437
  readonly POST: "POST";
430
438
  readonly PRODUCT: "PRODUCT";
439
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
440
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
431
441
  readonly COMMENT: "COMMENT";
432
442
  readonly JOB_APPLICATION: "JOB_APPLICATION";
433
443
  }>;
@@ -476,6 +486,8 @@ export declare const UserWithJobBookmarksOutputSchema: z.ZodObject<{
476
486
  readonly JOB: "JOB";
477
487
  readonly POST: "POST";
478
488
  readonly PRODUCT: "PRODUCT";
489
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
490
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
479
491
  readonly COMMENT: "COMMENT";
480
492
  readonly JOB_APPLICATION: "JOB_APPLICATION";
481
493
  }>;
@@ -521,6 +533,8 @@ export declare const UserWithProjectBookmarksEntitySchema: z.ZodObject<{
521
533
  readonly JOB: "JOB";
522
534
  readonly POST: "POST";
523
535
  readonly PRODUCT: "PRODUCT";
536
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
537
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
524
538
  readonly COMMENT: "COMMENT";
525
539
  readonly JOB_APPLICATION: "JOB_APPLICATION";
526
540
  }>;
@@ -592,6 +606,8 @@ export declare const UserWithPostBookmarksEntitySchema: z.ZodObject<{
592
606
  readonly JOB: "JOB";
593
607
  readonly POST: "POST";
594
608
  readonly PRODUCT: "PRODUCT";
609
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
610
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
595
611
  readonly COMMENT: "COMMENT";
596
612
  readonly JOB_APPLICATION: "JOB_APPLICATION";
597
613
  }>;
@@ -604,6 +620,8 @@ export declare const UserWithPostBookmarksEntitySchema: z.ZodObject<{
604
620
  readonly JOB: "JOB";
605
621
  readonly POST: "POST";
606
622
  readonly PRODUCT: "PRODUCT";
623
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
624
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
607
625
  readonly COMMENT: "COMMENT";
608
626
  readonly JOB_APPLICATION: "JOB_APPLICATION";
609
627
  }>>;
@@ -655,6 +673,8 @@ export declare const UserWithPostBookmarksEntitySchema: z.ZodObject<{
655
673
  readonly JOB: "JOB";
656
674
  readonly POST: "POST";
657
675
  readonly PRODUCT: "PRODUCT";
676
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
677
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
658
678
  readonly COMMENT: "COMMENT";
659
679
  readonly JOB_APPLICATION: "JOB_APPLICATION";
660
680
  }>>;
@@ -688,18 +708,33 @@ export declare const UserWithProductsEntitySchema: z.ZodObject<{
688
708
  category: z.ZodString;
689
709
  subcategory: z.ZodNullable<z.ZodOptional<z.ZodString>>;
690
710
  tags: z.ZodArray<z.ZodString>;
691
- coverImages: z.ZodDefault<z.ZodArray<z.ZodObject<{
692
- fileId: z.ZodCUID2;
693
- isThumbnail: z.ZodDefault<z.ZodBoolean>;
694
- order: z.ZodDefault<z.ZodNumber>;
711
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
712
+ id: z.ZodCUID2;
713
+ key: z.ZodString;
714
+ mimeType: z.ZodString;
695
715
  url: z.ZodURL;
716
+ parentId: z.ZodNullable<z.ZodCUID2>;
717
+ parentType: z.ZodNullable<z.ZodEnum<{
718
+ readonly PROJECT: "PROJECT";
719
+ readonly USER: "USER";
720
+ readonly JOB: "JOB";
721
+ readonly POST: "POST";
722
+ readonly PRODUCT: "PRODUCT";
723
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
724
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
725
+ readonly COMMENT: "COMMENT";
726
+ readonly JOB_APPLICATION: "JOB_APPLICATION";
727
+ }>>;
728
+ isThumbnail: z.ZodNullable<z.ZodBoolean>;
729
+ order: z.ZodNumber;
730
+ createdAt: z.ZodCoercedDate<unknown>;
731
+ updatedAt: z.ZodCoercedDate<unknown>;
732
+ deletedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
696
733
  }, z.core.$strip>>>;
697
- productFiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
698
- fileId: z.ZodCUID2;
699
- order: z.ZodDefault<z.ZodNumber>;
700
- url: z.ZodURL;
734
+ productLinks: z.ZodDefault<z.ZodArray<z.ZodObject<{
735
+ title: z.ZodNullable<z.ZodString>;
736
+ url: z.ZodString;
701
737
  }, z.core.$strip>>>;
702
- productLinks: z.ZodDefault<z.ZodArray<z.ZodURL>>;
703
738
  pricingModel: z.ZodEnum<{
704
739
  readonly FREE: "Free";
705
740
  readonly FIXED: "Fixed";
@@ -728,6 +763,10 @@ export declare const UserWithProductsEntitySchema: z.ZodObject<{
728
763
  discountCode: z.ZodOptional<z.ZodString>;
729
764
  expiry: z.ZodNullable<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
730
765
  }, z.core.$strip>>>;
766
+ ownsRights: z.ZodBoolean;
767
+ noHarmfulContent: z.ZodBoolean;
768
+ providesSupport: z.ZodBoolean;
769
+ agreesToTerms: z.ZodBoolean;
731
770
  supportEmail: z.ZodNullable<z.ZodOptional<z.ZodEmail>>;
732
771
  supportPhone: z.ZodNullable<z.ZodOptional<z.ZodString>>;
733
772
  createdAt: z.ZodCoercedDate<unknown>;
@@ -758,6 +797,8 @@ export declare const GetUserWithProjectBookmarksOutputSchema: z.ZodObject<{
758
797
  readonly JOB: "JOB";
759
798
  readonly POST: "POST";
760
799
  readonly PRODUCT: "PRODUCT";
800
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
801
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
761
802
  readonly COMMENT: "COMMENT";
762
803
  readonly JOB_APPLICATION: "JOB_APPLICATION";
763
804
  }>;
@@ -840,18 +881,33 @@ export declare const GetUserWithProductsOutputSchema: z.ZodObject<{
840
881
  category: z.ZodString;
841
882
  subcategory: z.ZodNullable<z.ZodOptional<z.ZodString>>;
842
883
  tags: z.ZodArray<z.ZodString>;
843
- coverImages: z.ZodDefault<z.ZodArray<z.ZodObject<{
844
- fileId: z.ZodCUID2;
845
- isThumbnail: z.ZodDefault<z.ZodBoolean>;
846
- order: z.ZodDefault<z.ZodNumber>;
884
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
885
+ id: z.ZodCUID2;
886
+ key: z.ZodString;
887
+ mimeType: z.ZodString;
847
888
  url: z.ZodURL;
889
+ parentId: z.ZodNullable<z.ZodCUID2>;
890
+ parentType: z.ZodNullable<z.ZodEnum<{
891
+ readonly PROJECT: "PROJECT";
892
+ readonly USER: "USER";
893
+ readonly JOB: "JOB";
894
+ readonly POST: "POST";
895
+ readonly PRODUCT: "PRODUCT";
896
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
897
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
898
+ readonly COMMENT: "COMMENT";
899
+ readonly JOB_APPLICATION: "JOB_APPLICATION";
900
+ }>>;
901
+ isThumbnail: z.ZodNullable<z.ZodBoolean>;
902
+ order: z.ZodNumber;
903
+ createdAt: z.ZodCoercedDate<unknown>;
904
+ updatedAt: z.ZodCoercedDate<unknown>;
905
+ deletedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
848
906
  }, z.core.$strip>>>;
849
- productFiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
850
- fileId: z.ZodCUID2;
851
- order: z.ZodDefault<z.ZodNumber>;
852
- url: z.ZodURL;
907
+ productLinks: z.ZodDefault<z.ZodArray<z.ZodObject<{
908
+ title: z.ZodNullable<z.ZodString>;
909
+ url: z.ZodString;
853
910
  }, z.core.$strip>>>;
854
- productLinks: z.ZodDefault<z.ZodArray<z.ZodURL>>;
855
911
  pricingModel: z.ZodEnum<{
856
912
  readonly FREE: "Free";
857
913
  readonly FIXED: "Fixed";
@@ -880,6 +936,10 @@ export declare const GetUserWithProductsOutputSchema: z.ZodObject<{
880
936
  discountCode: z.ZodOptional<z.ZodString>;
881
937
  expiry: z.ZodNullable<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
882
938
  }, z.core.$strip>>>;
939
+ ownsRights: z.ZodBoolean;
940
+ noHarmfulContent: z.ZodBoolean;
941
+ providesSupport: z.ZodBoolean;
942
+ agreesToTerms: z.ZodBoolean;
883
943
  supportEmail: z.ZodNullable<z.ZodOptional<z.ZodEmail>>;
884
944
  supportPhone: z.ZodNullable<z.ZodOptional<z.ZodString>>;
885
945
  createdAt: z.ZodCoercedDate<unknown>;
@@ -903,6 +963,8 @@ export declare const GetUserWithPostBookmarksOutputSchema: z.ZodObject<{
903
963
  readonly JOB: "JOB";
904
964
  readonly POST: "POST";
905
965
  readonly PRODUCT: "PRODUCT";
966
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
967
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
906
968
  readonly COMMENT: "COMMENT";
907
969
  readonly JOB_APPLICATION: "JOB_APPLICATION";
908
970
  }>;
@@ -915,6 +977,8 @@ export declare const GetUserWithPostBookmarksOutputSchema: z.ZodObject<{
915
977
  readonly JOB: "JOB";
916
978
  readonly POST: "POST";
917
979
  readonly PRODUCT: "PRODUCT";
980
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
981
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
918
982
  readonly COMMENT: "COMMENT";
919
983
  readonly JOB_APPLICATION: "JOB_APPLICATION";
920
984
  }>>;
@@ -966,6 +1030,8 @@ export declare const GetUserWithPostBookmarksOutputSchema: z.ZodObject<{
966
1030
  readonly JOB: "JOB";
967
1031
  readonly POST: "POST";
968
1032
  readonly PRODUCT: "PRODUCT";
1033
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
1034
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
969
1035
  readonly COMMENT: "COMMENT";
970
1036
  readonly JOB_APPLICATION: "JOB_APPLICATION";
971
1037
  }>>;
@@ -985,6 +1051,8 @@ export declare const GetUserWithPostBookmarksOutputSchema: z.ZodObject<{
985
1051
  readonly JOB: "JOB";
986
1052
  readonly POST: "POST";
987
1053
  readonly PRODUCT: "PRODUCT";
1054
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
1055
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
988
1056
  readonly COMMENT: "COMMENT";
989
1057
  readonly JOB_APPLICATION: "JOB_APPLICATION";
990
1058
  }>;
@@ -1384,6 +1452,8 @@ export declare const GetAuthenticatedUserWithProjectBookmarksOutputSchema: z.Zod
1384
1452
  readonly JOB: "JOB";
1385
1453
  readonly POST: "POST";
1386
1454
  readonly PRODUCT: "PRODUCT";
1455
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
1456
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
1387
1457
  readonly COMMENT: "COMMENT";
1388
1458
  readonly JOB_APPLICATION: "JOB_APPLICATION";
1389
1459
  }>;
@@ -1455,6 +1525,8 @@ export declare const GetAuthenticatedUserWithProjectLikesOutputSchema: z.ZodObje
1455
1525
  readonly JOB: "JOB";
1456
1526
  readonly POST: "POST";
1457
1527
  readonly PRODUCT: "PRODUCT";
1528
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
1529
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
1458
1530
  readonly COMMENT: "COMMENT";
1459
1531
  readonly JOB_APPLICATION: "JOB_APPLICATION";
1460
1532
  }>;
@@ -1542,6 +1614,8 @@ export declare const GetUserActivityOutputSchema: z.ZodArray<z.ZodObject<{
1542
1614
  JOB: "JOB";
1543
1615
  POST: "POST";
1544
1616
  PRODUCT: "PRODUCT";
1617
+ PRODUCT_COVER: "PRODUCT_COVER";
1618
+ PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
1545
1619
  COMMENT: "COMMENT";
1546
1620
  JOB_APPLICATION: "JOB_APPLICATION";
1547
1621
  }>;
@@ -11,6 +11,8 @@ export declare const ViewEntitySchema: z.ZodObject<{
11
11
  readonly JOB: "JOB";
12
12
  readonly POST: "POST";
13
13
  readonly PRODUCT: "PRODUCT";
14
+ readonly PRODUCT_COVER: "PRODUCT_COVER";
15
+ readonly PRODUCT_DELIVERY: "PRODUCT_DELIVERY";
14
16
  readonly COMMENT: "COMMENT";
15
17
  readonly JOB_APPLICATION: "JOB_APPLICATION";
16
18
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zyacreatives/shared",
3
- "version": "2.5.3",
3
+ "version": "2.5.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/constants.ts CHANGED
@@ -109,6 +109,8 @@ export const ACTIVITY_PARENT_TYPES = {
109
109
  JOB: "JOB",
110
110
  POST: "POST",
111
111
  PRODUCT: "PRODUCT",
112
+ PRODUCT_COVER: "PRODUCT_COVER",
113
+ PRODUCT_DELIVERY: "PRODUCT_DELIVERY",
112
114
  COMMENT: "COMMENT",
113
115
  JOB_APPLICATION: "JOB_APPLICATION",
114
116
  } as const;
@@ -8,10 +8,7 @@ export const FileEntitySchema = z
8
8
  mimeType: z.string().openapi({ example: "image/jpeg" }),
9
9
  url: z.url().openapi({ example: "https://example.com/file.jpg" }),
10
10
  parentId: z.cuid2().nullable().openapi({ example: "ckj1a2b3c0000xyz" }),
11
- parentType: z
12
- .enum(ACTIVITY_PARENT_TYPES)
13
- .nullable()
14
- .openapi({ example: "POST" }),
11
+ parentType: z.enum(ACTIVITY_PARENT_TYPES).nullable(),
15
12
  isThumbnail: z.boolean().nullable().openapi({ example: false }),
16
13
  order: z.number().int().openapi({ example: 0 }),
17
14
  createdAt: z.coerce.date().openapi({ example: "2025-10-14T08:00:00.000Z" }),
@@ -4,35 +4,9 @@ import {
4
4
  PRICING_MODELS,
5
5
  PRODUCT_STATUS,
6
6
  WAGES_CURRENCY,
7
+ ACTIVITY_PARENT_TYPES, // Assumes this includes 'PRODUCT_COVER' and 'PRODUCT_DELIVERY'
7
8
  } from "../constants";
8
-
9
- export const CoverImageInputSchema = z.object({
10
- key: z.string().openapi({ description: "Storage key of the uploaded file" }),
11
- mimeType: z.string().openapi({ example: "image/jpeg" }),
12
- isThumbnail: z.boolean().default(false),
13
- order: z.number().int().default(0),
14
- });
15
-
16
- export const DeliveryFileInputSchema = z.object({
17
- key: z.string().openapi({ description: "Storage key of the uploaded file" }),
18
- mimeType: z.string().openapi({ example: "application/zip" }),
19
- order: z.number().int().default(0),
20
- });
21
-
22
- export const ProductCoverImageEntitySchema = z.object({
23
- fileId: z
24
- .cuid2()
25
- .openapi({ example: "f123e4567-e89b-12d3-a456-426614174000" }),
26
- isThumbnail: z.boolean().default(false),
27
- order: z.number().int().default(0),
28
- });
29
-
30
- export const ProductDeliveryFileEntitySchema = z.object({
31
- fileId: z
32
- .cuid2()
33
- .openapi({ example: "f987e6543-e89b-12d3-a456-426614174000" }),
34
- order: z.number().int().default(0),
35
- });
9
+ import { CreateFileInputSchema, FileEntitySchema } from "./file";
36
10
 
37
11
  export const ProductDiscountEntitySchema = z.object({
38
12
  discountType: z.enum(DISCOUNT_TYPES),
@@ -48,41 +22,8 @@ export const ProductLinkSchema = z.object({
48
22
  title: z.string().nullable(),
49
23
  url: z.string(),
50
24
  });
51
- export type ProductLink = z.infer<typeof ProductLinkSchema>;
52
-
53
- export const BaseProductSchema = z.object({
54
- id: z.cuid2(),
55
- createdAt: z.date(),
56
- updatedAt: z.date(),
57
- deletedAt: z.date().nullable(),
58
- status: z.enum(PRODUCT_STATUS).default("DRAFT"),
59
- sellerId: z.cuid2(),
60
- title: z.string(),
61
- description: z.string(),
62
- keyFeatures: z.string(),
63
25
 
64
- category: z.string(),
65
- subcategory: z.string().nullable(),
66
- tags: z.array(z.string()).nullable(),
67
-
68
- productLinks: z.array(ProductLinkSchema).nullable(),
69
- pricingModel: z.enum(PRICING_MODELS),
70
- currency: z.enum(WAGES_CURRENCY),
71
- price: z.number().nullable(),
72
- suggestedPrice: z.number().nullable(),
73
- discounts: z
74
- .array(
75
- z.object({
76
- discountType: z.enum(DISCOUNT_TYPES),
77
- amount: z.number(),
78
- discountCode: z.string().optional().nullable(),
79
- expiry: z.coerce.date().optional().nullable(),
80
- }),
81
- )
82
- .nullable(),
83
- supportEmail: z.string().nullable(),
84
- supportPhone: z.string().nullable(),
85
- });
26
+ // --- 3. Input Validation Schemas ---
86
27
 
87
28
  const ProductCoreInputSchema = z.object({
88
29
  id: z.cuid2().openapi({ description: "Client-generated ID for the product" }),
@@ -94,26 +35,19 @@ const ProductCoreInputSchema = z.object({
94
35
  category: z.string().min(1, "Category is required"),
95
36
  subcategory: z.string().optional(),
96
37
  tags: z.array(z.string()).max(10, "Keep tags to a maximum of 10").default([]),
97
-
98
- coverImages: z
99
- .array(CoverImageInputSchema)
100
- .min(1, "At least one cover image is required")
101
- .max(5, "Maximum of 5 cover images allowed"),
102
- currency: z.enum(WAGES_CURRENCY),
103
- productFiles: z.array(DeliveryFileInputSchema).default([]),
104
-
38
+ files: z.array(CreateFileInputSchema).default([]),
105
39
  productLinks: z.array(ProductLinkSchema).default([]),
106
40
 
41
+ currency: z.enum(WAGES_CURRENCY),
107
42
  pricingModel: z.enum(PRICING_MODELS).default(PRICING_MODELS.FIXED),
108
-
109
43
  price: z.number().int("Must be a whole number").min(0).optional(),
110
44
  suggestedPrice: z.number().int("Must be in cents").min(0).optional(),
111
-
112
45
  discounts: z.array(ProductDiscountEntitySchema).max(3).default([]),
113
46
  });
114
47
 
115
48
  export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
116
49
  (data, ctx) => {
50
+ // Pricing Validation
117
51
  if (
118
52
  data.pricingModel === PRICING_MODELS.FIXED &&
119
53
  (!data.price || data.price <= 0)
@@ -128,15 +62,14 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
128
62
  if (
129
63
  data.pricingModel === PRICING_MODELS.PWYW &&
130
64
  data.suggestedPrice !== undefined &&
131
- data.price !== undefined
65
+ data.price !== undefined &&
66
+ data.suggestedPrice < data.price
132
67
  ) {
133
- if (data.suggestedPrice < data.price) {
134
- ctx.addIssue({
135
- code: "custom",
136
- message: "Suggested price cannot be lower than the minimum price.",
137
- path: ["suggestedPrice"],
138
- });
139
- }
68
+ ctx.addIssue({
69
+ code: "custom",
70
+ message: "Suggested price cannot be lower than the minimum price.",
71
+ path: ["suggestedPrice"],
72
+ });
140
73
  }
141
74
 
142
75
  if (
@@ -151,22 +84,38 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
151
84
  });
152
85
  }
153
86
 
154
- if (data.productFiles.length === 0 && data.productLinks.length === 0) {
87
+ // File Validation based on parentType
88
+ const deliveryFiles = data.files.filter(
89
+ (f) => f.parentType === "PRODUCT_DELIVERY",
90
+ );
91
+ const coverImages = data.files.filter(
92
+ (f) => f.parentType === "PRODUCT_COVER",
93
+ );
94
+
95
+ if (deliveryFiles.length === 0 && data.productLinks.length === 0) {
155
96
  ctx.addIssue({
156
97
  code: "custom",
157
98
  message:
158
99
  "You must provide at least one product file or a link for the buyer to receive.",
159
- path: ["productFiles"],
100
+ path: ["files"],
160
101
  });
161
102
  }
162
103
 
163
- const thumbnails = data.coverImages.filter((img) => img.isThumbnail);
164
- if (thumbnails.length !== 1) {
104
+ if (coverImages.length < 1 || coverImages.length > 5) {
165
105
  ctx.addIssue({
166
106
  code: "custom",
167
- message: "Exactly one cover image must be set as the thumbnail.",
168
- path: ["coverImages"],
107
+ message: "Between 1 and 5 cover images are required.",
108
+ path: ["files"],
169
109
  });
110
+ } else {
111
+ const thumbnails = coverImages.filter((img) => img.isThumbnail);
112
+ if (thumbnails.length !== 1) {
113
+ ctx.addIssue({
114
+ code: "custom",
115
+ message: "Exactly one cover image must be set as the thumbnail.",
116
+ path: ["files"],
117
+ });
118
+ }
170
119
  }
171
120
 
172
121
  data.discounts.forEach((discount, index) => {
@@ -182,15 +131,17 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
182
131
  });
183
132
  }
184
133
 
185
- if (isFixed && data.price !== undefined) {
186
- if (discount.amount >= data.price) {
187
- ctx.addIssue({
188
- code: "custom",
189
- message:
190
- "Fixed discount amounts must be less than the product price.",
191
- path: ["discounts", index, "amount"],
192
- });
193
- }
134
+ if (
135
+ isFixed &&
136
+ data.price !== undefined &&
137
+ discount.amount >= data.price
138
+ ) {
139
+ ctx.addIssue({
140
+ code: "custom",
141
+ message:
142
+ "Fixed discount amounts must be less than the product price.",
143
+ path: ["discounts", index, "amount"],
144
+ });
194
145
  }
195
146
  });
196
147
  },
@@ -198,22 +149,17 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
198
149
 
199
150
  export const ProductServiceAndComplianceInputSchema = z.object({
200
151
  id: z.cuid2().openapi({ description: "ID of the product" }),
201
-
202
152
  supportEmail: z.email("A valid support email is required"),
203
153
  supportPhone: z.string().optional(),
204
-
205
154
  ownsRights: z.literal(
206
155
  true,
207
- "You must confirm you own the rights to this product.",
156
+ '"You must confirm you own the rights to this product."',
208
157
  ),
209
-
210
158
  noHarmfulContent: z.literal(true, "You must confirm no harmful content."),
211
-
212
159
  providesSupport: z.boolean(),
213
160
  agreesToTerms: z.literal(true, "You must agree to the Terms."),
214
161
  });
215
162
 
216
- // The `id` override here ensures we use the existing DB id when updating
217
163
  export const UpdateProductInputSchema = ProductCoreInputSchema.extend(
218
164
  ProductServiceAndComplianceInputSchema.omit({ id: true }).shape,
219
165
  )
@@ -222,10 +168,11 @@ export const UpdateProductInputSchema = ProductCoreInputSchema.extend(
222
168
  id: z.cuid2().openapi({ description: "ID of the product being updated" }),
223
169
  });
224
170
 
171
+ // --- 4. Entity & Output Schemas ---
172
+
225
173
  export const ProductEntitySchema = z
226
174
  .object({
227
175
  id: z.cuid2(),
228
-
229
176
  sellerId: z.cuid2().openapi({ description: "ID of the creator/seller" }),
230
177
  sellerUsername: z.string(),
231
178
  sellerName: z.string(),
@@ -239,23 +186,23 @@ export const ProductEntitySchema = z
239
186
  subcategory: z.string().optional().nullable(),
240
187
  tags: z.array(z.string()),
241
188
 
242
- coverImages: z
243
- .array(ProductCoverImageEntitySchema.extend({ url: z.url() }))
244
- .default([]),
245
- productFiles: z
246
- .array(ProductDeliveryFileEntitySchema.extend({ url: z.url() }))
247
- .default([]),
248
- productLinks: z.array(z.url()).default([]),
189
+ // Unified files array for output
190
+ files: z.array(FileEntitySchema).default([]),
191
+ productLinks: z.array(ProductLinkSchema).default([]),
249
192
 
250
193
  pricingModel: z.enum(PRICING_MODELS),
251
194
  currency: z.enum(WAGES_CURRENCY),
252
195
  price: z.number().int().optional().nullable(),
253
196
  suggestedPrice: z.number().int().optional().nullable(),
254
-
255
197
  discounts: z.array(ProductDiscountEntitySchema).default([]),
256
198
 
199
+ ownsRights: z.boolean(),
200
+ noHarmfulContent: z.boolean(),
201
+ providesSupport: z.boolean(),
202
+ agreesToTerms: z.boolean(),
257
203
  supportEmail: z.email().optional().nullable(),
258
204
  supportPhone: z.string().optional().nullable(),
205
+
259
206
  createdAt: z.coerce.date(),
260
207
  updatedAt: z.coerce.date(),
261
208
  deletedAt: z.coerce.date().optional().nullable(),
@@ -313,11 +260,9 @@ export const GetMarketplaceInfoOutputSchema = z.object({
313
260
  communityFavourites: z.array(ProductSearchDocumentSchema),
314
261
  });
315
262
 
263
+ export type ProductLink = z.infer<typeof ProductLinkSchema>;
316
264
  export type SearchProductInput = z.infer<typeof SearchProductInputSchema>;
317
265
  export type SearchProductOutput = z.infer<typeof SearchProductOutputSchema>;
318
- export type CoverImageInput = z.infer<typeof CoverImageInputSchema>;
319
- export type DeliveryFileInput = z.infer<typeof DeliveryFileInputSchema>;
320
-
321
266
  export type MarketplaceCategoryOutput = z.infer<
322
267
  typeof MarketplaceCategorySchema
323
268
  >;
@@ -325,21 +270,11 @@ export type GetMarketplaceInfoOutput = z.infer<
325
270
  typeof GetMarketplaceInfoOutputSchema
326
271
  >;
327
272
 
328
- export type ProductCoverImageEntity = z.infer<
329
- typeof ProductCoverImageEntitySchema
330
- >;
331
-
332
- export type ProductDeliveryFileEntity = z.infer<
333
- typeof ProductDeliveryFileEntitySchema
334
- >;
335
273
  export type ProductDiscountEntity = z.infer<typeof ProductDiscountEntitySchema>;
336
-
337
274
  export type CreateProductInputEntity = z.infer<typeof CreateProductInputSchema>;
338
275
  export type ProductServiceAndComplianceInputEntity = z.infer<
339
276
  typeof ProductServiceAndComplianceInputSchema
340
277
  >;
341
278
  export type UpdateProductInputEntity = z.infer<typeof UpdateProductInputSchema>;
342
279
  export type ProductEntity = z.infer<typeof ProductEntitySchema>;
343
-
344
- export type BaseProductEntity = z.infer<typeof BaseProductSchema>;
345
280
  export type ProductSearchDocument = z.infer<typeof ProductSearchDocumentSchema>;