@zyacreatives/shared 2.5.4 → 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.
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/schemas/bookmark.d.ts +6 -0
- package/dist/schemas/comment.d.ts +4 -0
- package/dist/schemas/common.d.ts +2 -0
- package/dist/schemas/entity-stats.d.ts +2 -0
- package/dist/schemas/file.d.ts +8 -0
- package/dist/schemas/file.js +1 -4
- package/dist/schemas/like.d.ts +6 -0
- package/dist/schemas/message.d.ts +8 -0
- package/dist/schemas/notification.d.ts +12 -0
- package/dist/schemas/post.d.ts +38 -0
- package/dist/schemas/product.d.ts +66 -115
- package/dist/schemas/product.js +47 -89
- package/dist/schemas/project.d.ts +12 -0
- package/dist/schemas/transaction.d.ts +1 -1
- package/dist/schemas/user-strike.d.ts +6 -0
- package/dist/schemas/user.d.ts +86 -18
- package/dist/schemas/view.d.ts +2 -0
- package/package.json +1 -1
- package/src/constants.ts +2 -0
- package/src/schemas/file.ts +1 -4
- package/src/schemas/product.ts +58 -121
package/src/schemas/product.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
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: ["
|
|
100
|
+
path: ["files"],
|
|
160
101
|
});
|
|
161
102
|
}
|
|
162
103
|
|
|
163
|
-
|
|
164
|
-
if (thumbnails.length !== 1) {
|
|
104
|
+
if (coverImages.length < 1 || coverImages.length > 5) {
|
|
165
105
|
ctx.addIssue({
|
|
166
106
|
code: "custom",
|
|
167
|
-
message: "
|
|
168
|
-
path: ["
|
|
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 (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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,17 +149,13 @@ 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
|
});
|
|
@@ -221,10 +168,11 @@ export const UpdateProductInputSchema = ProductCoreInputSchema.extend(
|
|
|
221
168
|
id: z.cuid2().openapi({ description: "ID of the product being updated" }),
|
|
222
169
|
});
|
|
223
170
|
|
|
171
|
+
// --- 4. Entity & Output Schemas ---
|
|
172
|
+
|
|
224
173
|
export const ProductEntitySchema = z
|
|
225
174
|
.object({
|
|
226
175
|
id: z.cuid2(),
|
|
227
|
-
|
|
228
176
|
sellerId: z.cuid2().openapi({ description: "ID of the creator/seller" }),
|
|
229
177
|
sellerUsername: z.string(),
|
|
230
178
|
sellerName: z.string(),
|
|
@@ -238,22 +186,23 @@ export const ProductEntitySchema = z
|
|
|
238
186
|
subcategory: z.string().optional().nullable(),
|
|
239
187
|
tags: z.array(z.string()),
|
|
240
188
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
.default([]),
|
|
244
|
-
productFiles: z
|
|
245
|
-
.array(ProductDeliveryFileEntitySchema.extend({ url: z.url() }))
|
|
246
|
-
.default([]),
|
|
189
|
+
// Unified files array for output
|
|
190
|
+
files: z.array(FileEntitySchema).default([]),
|
|
247
191
|
productLinks: z.array(ProductLinkSchema).default([]),
|
|
192
|
+
|
|
248
193
|
pricingModel: z.enum(PRICING_MODELS),
|
|
249
194
|
currency: z.enum(WAGES_CURRENCY),
|
|
250
195
|
price: z.number().int().optional().nullable(),
|
|
251
196
|
suggestedPrice: z.number().int().optional().nullable(),
|
|
252
|
-
|
|
253
197
|
discounts: z.array(ProductDiscountEntitySchema).default([]),
|
|
254
198
|
|
|
199
|
+
ownsRights: z.boolean(),
|
|
200
|
+
noHarmfulContent: z.boolean(),
|
|
201
|
+
providesSupport: z.boolean(),
|
|
202
|
+
agreesToTerms: z.boolean(),
|
|
255
203
|
supportEmail: z.email().optional().nullable(),
|
|
256
204
|
supportPhone: z.string().optional().nullable(),
|
|
205
|
+
|
|
257
206
|
createdAt: z.coerce.date(),
|
|
258
207
|
updatedAt: z.coerce.date(),
|
|
259
208
|
deletedAt: z.coerce.date().optional().nullable(),
|
|
@@ -311,11 +260,9 @@ export const GetMarketplaceInfoOutputSchema = z.object({
|
|
|
311
260
|
communityFavourites: z.array(ProductSearchDocumentSchema),
|
|
312
261
|
});
|
|
313
262
|
|
|
263
|
+
export type ProductLink = z.infer<typeof ProductLinkSchema>;
|
|
314
264
|
export type SearchProductInput = z.infer<typeof SearchProductInputSchema>;
|
|
315
265
|
export type SearchProductOutput = z.infer<typeof SearchProductOutputSchema>;
|
|
316
|
-
export type CoverImageInput = z.infer<typeof CoverImageInputSchema>;
|
|
317
|
-
export type DeliveryFileInput = z.infer<typeof DeliveryFileInputSchema>;
|
|
318
|
-
|
|
319
266
|
export type MarketplaceCategoryOutput = z.infer<
|
|
320
267
|
typeof MarketplaceCategorySchema
|
|
321
268
|
>;
|
|
@@ -323,21 +270,11 @@ export type GetMarketplaceInfoOutput = z.infer<
|
|
|
323
270
|
typeof GetMarketplaceInfoOutputSchema
|
|
324
271
|
>;
|
|
325
272
|
|
|
326
|
-
export type ProductCoverImageEntity = z.infer<
|
|
327
|
-
typeof ProductCoverImageEntitySchema
|
|
328
|
-
>;
|
|
329
|
-
|
|
330
|
-
export type ProductDeliveryFileEntity = z.infer<
|
|
331
|
-
typeof ProductDeliveryFileEntitySchema
|
|
332
|
-
>;
|
|
333
273
|
export type ProductDiscountEntity = z.infer<typeof ProductDiscountEntitySchema>;
|
|
334
|
-
|
|
335
274
|
export type CreateProductInputEntity = z.infer<typeof CreateProductInputSchema>;
|
|
336
275
|
export type ProductServiceAndComplianceInputEntity = z.infer<
|
|
337
276
|
typeof ProductServiceAndComplianceInputSchema
|
|
338
277
|
>;
|
|
339
278
|
export type UpdateProductInputEntity = z.infer<typeof UpdateProductInputSchema>;
|
|
340
279
|
export type ProductEntity = z.infer<typeof ProductEntitySchema>;
|
|
341
|
-
|
|
342
|
-
export type BaseProductEntity = z.infer<typeof BaseProductSchema>;
|
|
343
280
|
export type ProductSearchDocument = z.infer<typeof ProductSearchDocumentSchema>;
|