@zyacreatives/shared 2.2.87 → 2.2.89
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 +11 -0
- package/dist/constants.js +10 -1
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/post.js +97 -40
- package/dist/schemas/product.d.ts +96 -0
- package/dist/schemas/product.js +119 -0
- package/dist/schemas/seller.d.ts +39 -0
- package/dist/schemas/seller.js +5 -1
- package/package.json +1 -1
- package/src/constants.ts +13 -0
- package/src/schemas/index.ts +1 -0
- package/src/schemas/post.ts +139 -81
- package/src/schemas/product.ts +153 -0
- package/src/schemas/seller.ts +7 -0
package/dist/constants.d.ts
CHANGED
|
@@ -280,6 +280,15 @@ export declare const GATEWAY_PROVIDER: {
|
|
|
280
280
|
readonly PAYSTACK: "PAYSTACK";
|
|
281
281
|
readonly STRIPE: "STRIPE";
|
|
282
282
|
};
|
|
283
|
+
export declare const PRICING_MODELS: {
|
|
284
|
+
readonly FREE: "Free";
|
|
285
|
+
readonly FIXED: "Fixed";
|
|
286
|
+
readonly PWYW: "Pay What You Want";
|
|
287
|
+
};
|
|
288
|
+
export declare const DISCOUNT_TYPES: {
|
|
289
|
+
readonly FIXED_AMOUNT: "Fixed Amount";
|
|
290
|
+
readonly PERCENTAGE: "Percentage";
|
|
291
|
+
};
|
|
283
292
|
export type SignalInterestType = (typeof SIGNAL_INTEREST_TYPES)[keyof typeof SIGNAL_INTEREST_TYPES];
|
|
284
293
|
export type SignalStatus = (typeof SIGNAL_STATUS)[keyof typeof SIGNAL_STATUS];
|
|
285
294
|
export type NotificationType = (typeof NOTIFICATION_TYPES)[keyof typeof NOTIFICATION_TYPES];
|
|
@@ -316,6 +325,8 @@ export type SellerStatus = (typeof SELLER_STATUS)[keyof typeof SELLER_STATUS];
|
|
|
316
325
|
export type CountryOfOperation = (typeof COUNTRY_OF_OPERATION)[keyof typeof COUNTRY_OF_OPERATION];
|
|
317
326
|
export type GatewayProvider = (typeof GATEWAY_PROVIDER)[keyof typeof GATEWAY_PROVIDER];
|
|
318
327
|
export type PaymentMethodStatus = (typeof PAYMENT_METHOD_STATUS)[keyof typeof PAYMENT_METHOD_STATUS];
|
|
328
|
+
export type PricingModel = (typeof PRICING_MODELS)[keyof typeof PRICING_MODELS];
|
|
329
|
+
export type DiscountType = (typeof DISCOUNT_TYPES)[keyof typeof DISCOUNT_TYPES];
|
|
319
330
|
export declare const API_ROUTES: {
|
|
320
331
|
readonly healthCheck: "/health";
|
|
321
332
|
readonly username: {
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ANALYTICS_EVENTS = exports.DEFAULT_DISCIPLINES = exports.API_ROUTES = exports.GATEWAY_PROVIDER = exports.COUNTRY_OF_OPERATION = exports.SIGNAL_STATUS = exports.SIGNAL_INTEREST_TYPES = exports.VENTURE_STAGES = exports.NOTIFICATION_TYPES = exports.APPLICATION_STATUS = exports.LINK_TYPES = exports.ACTIVITY_TYPES = exports.POST_BADGE_TYPES = exports.PROJECT_STATUS = exports.MESSAGE_REQUEST_STATUS = exports.JOB_STATUS = exports.WAGES_CURRENCY = exports.GIG_TYPE = exports.MESSAGE_TYPES = exports.JOB_LOCATIONS = exports.JOB_SECTIONS = exports.WAGE_TYPES = exports.JOB_AVAILABILITY_TYPES = exports.EMPLOYMENT_TYPE = exports.WORK_MODE = exports.JOB_TYPE = exports.POST_TYPES = exports.ACTIVITY_PARENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_STATUSES = exports.GEOGRAPHIC_FOCUS = exports.INVESTMENT_SIZES = exports.INVESTOR_TYPES = exports.ONBOARDING_PAGES = exports.PAYMENT_METHOD_STATUS = exports.SELLER_STATUS = exports.EXPERIENCE_LEVELS = exports.CLIENT_TYPES = exports.USER_STATUSES = exports.ROLES = void 0;
|
|
3
|
+
exports.ANALYTICS_EVENTS = exports.DEFAULT_DISCIPLINES = exports.API_ROUTES = exports.DISCOUNT_TYPES = exports.PRICING_MODELS = exports.GATEWAY_PROVIDER = exports.COUNTRY_OF_OPERATION = exports.SIGNAL_STATUS = exports.SIGNAL_INTEREST_TYPES = exports.VENTURE_STAGES = exports.NOTIFICATION_TYPES = exports.APPLICATION_STATUS = exports.LINK_TYPES = exports.ACTIVITY_TYPES = exports.POST_BADGE_TYPES = exports.PROJECT_STATUS = exports.MESSAGE_REQUEST_STATUS = exports.JOB_STATUS = exports.WAGES_CURRENCY = exports.GIG_TYPE = exports.MESSAGE_TYPES = exports.JOB_LOCATIONS = exports.JOB_SECTIONS = exports.WAGE_TYPES = exports.JOB_AVAILABILITY_TYPES = exports.EMPLOYMENT_TYPE = exports.WORK_MODE = exports.JOB_TYPE = exports.POST_TYPES = exports.ACTIVITY_PARENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_STATUSES = exports.GEOGRAPHIC_FOCUS = exports.INVESTMENT_SIZES = exports.INVESTOR_TYPES = exports.ONBOARDING_PAGES = exports.PAYMENT_METHOD_STATUS = exports.SELLER_STATUS = exports.EXPERIENCE_LEVELS = exports.CLIENT_TYPES = exports.USER_STATUSES = exports.ROLES = void 0;
|
|
4
4
|
exports.ROLES = {
|
|
5
5
|
CREATIVE: "CREATIVE",
|
|
6
6
|
BRAND: "BRAND",
|
|
@@ -278,6 +278,15 @@ exports.GATEWAY_PROVIDER = {
|
|
|
278
278
|
PAYSTACK: "PAYSTACK",
|
|
279
279
|
STRIPE: "STRIPE",
|
|
280
280
|
};
|
|
281
|
+
exports.PRICING_MODELS = {
|
|
282
|
+
FREE: "Free",
|
|
283
|
+
FIXED: "Fixed",
|
|
284
|
+
PWYW: "Pay What You Want",
|
|
285
|
+
};
|
|
286
|
+
exports.DISCOUNT_TYPES = {
|
|
287
|
+
FIXED_AMOUNT: "Fixed Amount",
|
|
288
|
+
PERCENTAGE: "Percentage",
|
|
289
|
+
};
|
|
281
290
|
exports.API_ROUTES = {
|
|
282
291
|
healthCheck: "/health",
|
|
283
292
|
username: {
|
package/dist/schemas/index.d.ts
CHANGED
package/dist/schemas/index.js
CHANGED
package/dist/schemas/post.js
CHANGED
|
@@ -29,10 +29,7 @@ exports.PostEntitySchema = zod_openapi_1.z.object({
|
|
|
29
29
|
.openapi({
|
|
30
30
|
example: [{ name: "javascript", id: 101 }],
|
|
31
31
|
}),
|
|
32
|
-
badge: zod_openapi_1.z
|
|
33
|
-
.enum(constants_1.POST_BADGE_TYPES)
|
|
34
|
-
.optional()
|
|
35
|
-
.openapi({ example: "FEATURED" }),
|
|
32
|
+
badge: zod_openapi_1.z.enum(constants_1.POST_BADGE_TYPES).optional().openapi({ example: "FEATURED" }),
|
|
36
33
|
userId: zod_openapi_1.z
|
|
37
34
|
.cuid2()
|
|
38
35
|
.openapi({ description: "User id", example: "ckj1a2b3c0000def" }),
|
|
@@ -40,10 +37,7 @@ exports.PostEntitySchema = zod_openapi_1.z.object({
|
|
|
40
37
|
.string()
|
|
41
38
|
.optional()
|
|
42
39
|
.openapi({ description: "Username", example: "dev_guru" }),
|
|
43
|
-
creatorFullName: zod_openapi_1.z
|
|
44
|
-
.string()
|
|
45
|
-
.optional()
|
|
46
|
-
.openapi({ example: "Jane Doe" }),
|
|
40
|
+
creatorFullName: zod_openapi_1.z.string().optional().openapi({ example: "Jane Doe" }),
|
|
47
41
|
creatorImageUrl: zod_openapi_1.z
|
|
48
42
|
.cuid2()
|
|
49
43
|
.optional()
|
|
@@ -65,8 +59,7 @@ exports.PostEntitySchema = zod_openapi_1.z.object({
|
|
|
65
59
|
title: "Post Type",
|
|
66
60
|
example: "PROJECT",
|
|
67
61
|
}),
|
|
68
|
-
createdAt: zod_openapi_1.z
|
|
69
|
-
.coerce
|
|
62
|
+
createdAt: zod_openapi_1.z.coerce
|
|
70
63
|
.date()
|
|
71
64
|
.optional()
|
|
72
65
|
.openapi({ example: "2026-03-11T14:43:09Z" }),
|
|
@@ -98,14 +91,17 @@ exports.PostFileEntitySchema = zod_openapi_1.z
|
|
|
98
91
|
.object({
|
|
99
92
|
id: zod_openapi_1.z
|
|
100
93
|
.cuid2()
|
|
101
|
-
.openapi({
|
|
94
|
+
.openapi({
|
|
95
|
+
description: "CUID2 of the project file record.",
|
|
96
|
+
example: "cxy1a2b3c0000qwe",
|
|
97
|
+
}),
|
|
102
98
|
postId: zod_openapi_1.z.cuid2().openapi({
|
|
103
99
|
description: "CUID2 of the post this file belongs to.",
|
|
104
100
|
example: "ckj1a2b3c0000xyz",
|
|
105
101
|
}),
|
|
106
102
|
fileId: zod_openapi_1.z.cuid2().openapi({
|
|
107
103
|
description: "CUID2 of the linked file.",
|
|
108
|
-
example: "cvb1a2b3c0000rty"
|
|
104
|
+
example: "cvb1a2b3c0000rty",
|
|
109
105
|
}),
|
|
110
106
|
order: zod_openapi_1.z.number().int().openapi({
|
|
111
107
|
description: "Order index of the file in the project.",
|
|
@@ -130,9 +126,9 @@ exports.PostWithFilesEntitySchema = exports.PostEntitySchema.extend({
|
|
|
130
126
|
postId: "ckj1a2b3c0000xyz",
|
|
131
127
|
fileId: "cvb1a2b3c0000rty",
|
|
132
128
|
order: 1,
|
|
133
|
-
url: "https://cdn.example.com/image.png"
|
|
134
|
-
}
|
|
135
|
-
]
|
|
129
|
+
url: "https://cdn.example.com/image.png",
|
|
130
|
+
},
|
|
131
|
+
],
|
|
136
132
|
}),
|
|
137
133
|
});
|
|
138
134
|
exports.CreatePostInputSchema = zod_openapi_1.z.object({
|
|
@@ -169,17 +165,22 @@ exports.CreatePostInputSchema = zod_openapi_1.z.object({
|
|
|
169
165
|
.max(5, { message: "Cannot attach more than 5 files" })
|
|
170
166
|
.optional()
|
|
171
167
|
.openapi({
|
|
172
|
-
example: [{ fileId: "cvb1a2b3c0000rty", order: 1 }]
|
|
168
|
+
example: [{ fileId: "cvb1a2b3c0000rty", order: 1 }],
|
|
173
169
|
}),
|
|
174
170
|
tags: zod_openapi_1.z
|
|
175
|
-
.array(zod_openapi_1.z
|
|
171
|
+
.array(zod_openapi_1.z
|
|
172
|
+
.string()
|
|
173
|
+
.min(1, { message: "Tag cannot be empty" })
|
|
174
|
+
.openapi({ example: "react" }))
|
|
176
175
|
.max(3, { message: "Cannot add more than 3 tags" })
|
|
177
176
|
.optional()
|
|
178
177
|
.openapi({ example: ["react", "frontend"] }),
|
|
179
178
|
badge: zod_openapi_1.z.enum(constants_1.POST_BADGE_TYPES).optional().openapi({ example: "TRENDING" }),
|
|
180
179
|
linkMeta: zod_openapi_1.z
|
|
181
180
|
.object({
|
|
182
|
-
url: zod_openapi_1.z
|
|
181
|
+
url: zod_openapi_1.z
|
|
182
|
+
.url({ message: "Invalid URL format" })
|
|
183
|
+
.openapi({ example: "https://example.com" }),
|
|
183
184
|
title: zod_openapi_1.z
|
|
184
185
|
.string()
|
|
185
186
|
.max(200, { message: "Title cannot exceed 200 characters" })
|
|
@@ -192,7 +193,10 @@ exports.CreatePostInputSchema = zod_openapi_1.z.object({
|
|
|
192
193
|
})
|
|
193
194
|
.optional()
|
|
194
195
|
.openapi({ example: "This is an example link" }),
|
|
195
|
-
image: zod_openapi_1.z
|
|
196
|
+
image: zod_openapi_1.z
|
|
197
|
+
.url({ message: "Invalid image URL" })
|
|
198
|
+
.optional()
|
|
199
|
+
.openapi({ example: "https://example.com/preview.jpg" }),
|
|
196
200
|
})
|
|
197
201
|
.optional()
|
|
198
202
|
.openapi({
|
|
@@ -208,7 +212,7 @@ exports.CreatePostInputSchema = zod_openapi_1.z.object({
|
|
|
208
212
|
exports.CreatePostOutputSchema = exports.PostEntitySchema;
|
|
209
213
|
exports.GetPostOutputSchema = exports.PostWithFilesEntitySchema;
|
|
210
214
|
exports.PostIdSchema = zod_openapi_1.z.object({
|
|
211
|
-
postId: zod_openapi_1.z.cuid2().openapi({ example: "ckj1a2b3c0000xyz" })
|
|
215
|
+
postId: zod_openapi_1.z.cuid2().openapi({ example: "ckj1a2b3c0000xyz" }),
|
|
212
216
|
});
|
|
213
217
|
exports.MinimalPostSchema = exports.PostEntitySchema.pick({
|
|
214
218
|
id: true,
|
|
@@ -216,15 +220,21 @@ exports.MinimalPostSchema = exports.PostEntitySchema.pick({
|
|
|
216
220
|
content: true,
|
|
217
221
|
});
|
|
218
222
|
exports.PostWithLikesEntitySchema = exports.MinimalPostSchema.extend({
|
|
219
|
-
likes: zod_openapi_1.z
|
|
223
|
+
likes: zod_openapi_1.z
|
|
224
|
+
.array(activity_1.ActivitySchema.extend({
|
|
220
225
|
followsYou: zod_openapi_1.z.boolean().optional().openapi({ example: true }),
|
|
221
226
|
isFollowing: zod_openapi_1.z.boolean().optional().openapi({ example: false }),
|
|
222
|
-
}))
|
|
227
|
+
}))
|
|
228
|
+
.openapi({ example: [] }),
|
|
223
229
|
}).openapi({
|
|
224
230
|
title: "PostWithPostLikesEntity",
|
|
225
231
|
});
|
|
226
232
|
exports.GetPostWithLikesOutputSchema = exports.PostWithLikesEntitySchema.extend({
|
|
227
|
-
nextCursor: zod_openapi_1.z
|
|
233
|
+
nextCursor: zod_openapi_1.z
|
|
234
|
+
.string()
|
|
235
|
+
.optional()
|
|
236
|
+
.nullable()
|
|
237
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
228
238
|
});
|
|
229
239
|
exports.PostWithCommentsEntitySchema = exports.MinimalPostSchema.extend({
|
|
230
240
|
comments: zod_openapi_1.z.array(comment_1.CommentEntitySchema).openapi({ example: [] }),
|
|
@@ -232,7 +242,11 @@ exports.PostWithCommentsEntitySchema = exports.MinimalPostSchema.extend({
|
|
|
232
242
|
title: "PostWithPostCommentsEntity",
|
|
233
243
|
});
|
|
234
244
|
exports.GetPostWithCommentsOutputSchema = exports.PostWithCommentsEntitySchema.extend({
|
|
235
|
-
nextCursor: zod_openapi_1.z
|
|
245
|
+
nextCursor: zod_openapi_1.z
|
|
246
|
+
.string()
|
|
247
|
+
.optional()
|
|
248
|
+
.nullable()
|
|
249
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
236
250
|
});
|
|
237
251
|
exports.PostWithBookmarksEntitySchema = exports.MinimalPostSchema.extend({
|
|
238
252
|
bookmarks: zod_openapi_1.z.array(activity_1.ActivitySchema).openapi({ example: [] }),
|
|
@@ -247,9 +261,18 @@ exports.LinkPreviewInputSchema = zod_openapi_1.z.object({
|
|
|
247
261
|
});
|
|
248
262
|
exports.LinkPreviewOutputSchema = zod_openapi_1.z.object({
|
|
249
263
|
title: zod_openapi_1.z.string().openapi({ example: "Great Article" }),
|
|
250
|
-
description: zod_openapi_1.z
|
|
251
|
-
|
|
252
|
-
|
|
264
|
+
description: zod_openapi_1.z
|
|
265
|
+
.string()
|
|
266
|
+
.optional()
|
|
267
|
+
.openapi({ example: "A detailed breakdown of the topic." }),
|
|
268
|
+
image: zod_openapi_1.z
|
|
269
|
+
.string()
|
|
270
|
+
.optional()
|
|
271
|
+
.openapi({ example: "https://example.com/hero.jpg" }),
|
|
272
|
+
url: zod_openapi_1.z
|
|
273
|
+
.string()
|
|
274
|
+
.optional()
|
|
275
|
+
.openapi({ example: "https://example.com/article" }),
|
|
253
276
|
});
|
|
254
277
|
exports.FeedPostEntitySchema = exports.PostWithFilesEntitySchema.extend({
|
|
255
278
|
stats: entity_stats_1.EntityStatsSchema,
|
|
@@ -264,7 +287,11 @@ exports.GetFeedInputSchema = zod_openapi_1.z.object({
|
|
|
264
287
|
});
|
|
265
288
|
exports.GetFeedOutputSchema = zod_openapi_1.z.object({
|
|
266
289
|
feed: zod_openapi_1.z.array(exports.FeedPostEntitySchema).openapi({ example: [] }),
|
|
267
|
-
nextCursor: zod_openapi_1.z
|
|
290
|
+
nextCursor: zod_openapi_1.z
|
|
291
|
+
.string()
|
|
292
|
+
.optional()
|
|
293
|
+
.nullable()
|
|
294
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
268
295
|
});
|
|
269
296
|
exports.SearchPostInputSchema = zod_openapi_1.z.object({
|
|
270
297
|
queryString: zod_openapi_1.z
|
|
@@ -276,7 +303,11 @@ exports.SearchPostInputSchema = zod_openapi_1.z.object({
|
|
|
276
303
|
});
|
|
277
304
|
exports.SearchPostOutputSchema = zod_openapi_1.z.object({
|
|
278
305
|
posts: zod_openapi_1.z.array(exports.FeedPostEntitySchema).openapi({ example: [] }),
|
|
279
|
-
nextCursor: zod_openapi_1.z
|
|
306
|
+
nextCursor: zod_openapi_1.z
|
|
307
|
+
.string()
|
|
308
|
+
.optional()
|
|
309
|
+
.nullable()
|
|
310
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
280
311
|
});
|
|
281
312
|
exports.ReportPostInputSchema = zod_openapi_1.z.object({
|
|
282
313
|
complaint: zod_openapi_1.z
|
|
@@ -301,8 +332,12 @@ exports.PostAnalyticsOutputSchema = zod_openapi_1.z.object({
|
|
|
301
332
|
comments: zod_openapi_1.z.number().openapi({ example: 34 }),
|
|
302
333
|
linkCopied: zod_openapi_1.z.number().openapi({ example: 12 }),
|
|
303
334
|
bookmarks: zod_openapi_1.z.number().openapi({ example: 56 }),
|
|
304
|
-
tagsClicked: zod_openapi_1.z
|
|
305
|
-
|
|
335
|
+
tagsClicked: zod_openapi_1.z
|
|
336
|
+
.array(AnalyticsChartItemSchema)
|
|
337
|
+
.openapi({ example: [{ x: "javascript", y: 25 }] }),
|
|
338
|
+
platformShares: zod_openapi_1.z
|
|
339
|
+
.array(AnalyticsChartItemSchema)
|
|
340
|
+
.openapi({ example: [{ x: "Twitter", y: 10 }] }),
|
|
306
341
|
}),
|
|
307
342
|
behavior: zod_openapi_1.z.object({
|
|
308
343
|
viralityScore: zod_openapi_1.z.number().openapi({ example: 8.5 }),
|
|
@@ -318,26 +353,44 @@ exports.PostAnalyticsOutputSchema = zod_openapi_1.z.object({
|
|
|
318
353
|
}),
|
|
319
354
|
}),
|
|
320
355
|
});
|
|
321
|
-
exports.PostSearchDocumentSchema = zod_openapi_1.z
|
|
356
|
+
exports.PostSearchDocumentSchema = zod_openapi_1.z
|
|
357
|
+
.object({
|
|
322
358
|
id: zod_openapi_1.z.cuid2().openapi({ example: "ckj1a2b3c0000doc" }),
|
|
323
359
|
userId: zod_openapi_1.z.cuid2().openapi({ example: "ckj1a2b3c0000usr" }),
|
|
324
360
|
parentId: zod_openapi_1.z.cuid2().nullable().openapi({ example: "ckj1a2b3c0000prt" }),
|
|
325
361
|
parentType: zod_openapi_1.z.enum(constants_1.ACTIVITY_PARENT_TYPES).openapi({ example: "POST" }),
|
|
326
362
|
creatorUsername: zod_openapi_1.z.string().nullable().openapi({ example: "tech_lead" }),
|
|
327
363
|
creatorFullName: zod_openapi_1.z.string().nullable().openapi({ example: "Alex Smith" }),
|
|
328
|
-
creatorImageUrl: zod_openapi_1.z
|
|
364
|
+
creatorImageUrl: zod_openapi_1.z
|
|
365
|
+
.cuid2()
|
|
366
|
+
.nullable()
|
|
367
|
+
.openapi({ example: "clm1a2b3c0000pic" }),
|
|
329
368
|
tagIds: zod_openapi_1.z.array(zod_openapi_1.z.number()).openapi({ example: [101, 102] }),
|
|
330
369
|
tagNames: zod_openapi_1.z.array(zod_openapi_1.z.string()).openapi({ example: ["react", "typescript"] }),
|
|
331
370
|
badge: zod_openapi_1.z.enum(constants_1.POST_BADGE_TYPES).nullable().openapi({ example: "TRENDING" }),
|
|
332
371
|
postType: zod_openapi_1.z.enum(constants_1.POST_TYPES).openapi({ example: "PROJECT" }),
|
|
333
|
-
content: zod_openapi_1.z
|
|
372
|
+
content: zod_openapi_1.z
|
|
373
|
+
.string()
|
|
374
|
+
.nullable()
|
|
375
|
+
.openapi({ example: "Here is my latest open source tool." }),
|
|
334
376
|
linkTitle: zod_openapi_1.z.string().nullable().openapi({ example: "GitHub Repo" }),
|
|
335
|
-
linkDescription: zod_openapi_1.z
|
|
336
|
-
|
|
337
|
-
|
|
377
|
+
linkDescription: zod_openapi_1.z
|
|
378
|
+
.string()
|
|
379
|
+
.nullable()
|
|
380
|
+
.openapi({ example: "A fast, modern build system." }),
|
|
381
|
+
linkUrl: zod_openapi_1.z
|
|
382
|
+
.url()
|
|
383
|
+
.nullable()
|
|
384
|
+
.openapi({ example: "https://github.com/project" }),
|
|
385
|
+
linkImage: zod_openapi_1.z
|
|
386
|
+
.url()
|
|
387
|
+
.nullable()
|
|
388
|
+
.openapi({ example: "https://github.com/image.png" }),
|
|
338
389
|
postFiles: zod_openapi_1.z
|
|
339
390
|
.array(exports.PostFileEntitySchema.extend({
|
|
340
|
-
url: zod_openapi_1.z
|
|
391
|
+
url: zod_openapi_1.z
|
|
392
|
+
.url()
|
|
393
|
+
.openapi({ example: "https://cdn.example.com/file1.png" }),
|
|
341
394
|
}))
|
|
342
395
|
.nullable()
|
|
343
396
|
.openapi({
|
|
@@ -351,8 +404,12 @@ exports.PostSearchDocumentSchema = zod_openapi_1.z.object({
|
|
|
351
404
|
},
|
|
352
405
|
],
|
|
353
406
|
}),
|
|
354
|
-
createdAt: zod_openapi_1.z
|
|
355
|
-
|
|
407
|
+
createdAt: zod_openapi_1.z
|
|
408
|
+
.string()
|
|
409
|
+
.nullable()
|
|
410
|
+
.openapi({ example: "2026-03-11T14:43:09.000Z" }),
|
|
411
|
+
})
|
|
412
|
+
.openapi({
|
|
356
413
|
title: "Post Search Document",
|
|
357
414
|
description: "Flattened schema used for indexing posts in search engines.",
|
|
358
415
|
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
export declare const ProductCoverImageEntitySchema: z.ZodObject<{
|
|
3
|
+
fileId: z.ZodCUID2;
|
|
4
|
+
isThumbnail: z.ZodDefault<z.ZodBoolean>;
|
|
5
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export declare const ProductDeliveryFileEntitySchema: z.ZodObject<{
|
|
8
|
+
fileId: z.ZodCUID2;
|
|
9
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const ProductDiscountEntitySchema: z.ZodObject<{
|
|
12
|
+
discountType: z.ZodEnum<{
|
|
13
|
+
readonly FIXED_AMOUNT: "Fixed Amount";
|
|
14
|
+
readonly PERCENTAGE: "Percentage";
|
|
15
|
+
}>;
|
|
16
|
+
amount: z.ZodNumber;
|
|
17
|
+
discountCode: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export declare const CreateProductInputSchema: z.ZodObject<{
|
|
20
|
+
title: z.ZodString;
|
|
21
|
+
description: z.ZodString;
|
|
22
|
+
keyFeatures: z.ZodString;
|
|
23
|
+
category: z.ZodString;
|
|
24
|
+
subcategory: z.ZodOptional<z.ZodString>;
|
|
25
|
+
tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
26
|
+
coverImages: z.ZodArray<z.ZodObject<{
|
|
27
|
+
fileId: z.ZodCUID2;
|
|
28
|
+
isThumbnail: z.ZodDefault<z.ZodBoolean>;
|
|
29
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
productFiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
32
|
+
fileId: z.ZodCUID2;
|
|
33
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
34
|
+
}, z.core.$strip>>>;
|
|
35
|
+
productLinks: z.ZodDefault<z.ZodArray<z.ZodURL>>;
|
|
36
|
+
pricingModel: z.ZodDefault<z.ZodEnum<{
|
|
37
|
+
readonly FREE: "Free";
|
|
38
|
+
readonly FIXED: "Fixed";
|
|
39
|
+
readonly PWYW: "Pay What You Want";
|
|
40
|
+
}>>;
|
|
41
|
+
currency: z.ZodDefault<z.ZodString>;
|
|
42
|
+
price: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
suggestedPrice: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
discounts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
45
|
+
discountType: z.ZodEnum<{
|
|
46
|
+
readonly FIXED_AMOUNT: "Fixed Amount";
|
|
47
|
+
readonly PERCENTAGE: "Percentage";
|
|
48
|
+
}>;
|
|
49
|
+
amount: z.ZodNumber;
|
|
50
|
+
discountCode: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>>>;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
export declare const ProductEntitySchema: z.ZodObject<{
|
|
54
|
+
id: z.ZodCUID2;
|
|
55
|
+
userId: z.ZodCUID2;
|
|
56
|
+
title: z.ZodString;
|
|
57
|
+
description: z.ZodString;
|
|
58
|
+
keyFeatures: z.ZodString;
|
|
59
|
+
category: z.ZodString;
|
|
60
|
+
subcategory: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
61
|
+
tags: z.ZodArray<z.ZodString>;
|
|
62
|
+
coverImages: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
63
|
+
fileId: z.ZodCUID2;
|
|
64
|
+
isThumbnail: z.ZodDefault<z.ZodBoolean>;
|
|
65
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
66
|
+
}, z.core.$strip>>>;
|
|
67
|
+
productFiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
68
|
+
fileId: z.ZodCUID2;
|
|
69
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
70
|
+
}, z.core.$strip>>>;
|
|
71
|
+
productLinks: z.ZodDefault<z.ZodArray<z.ZodURL>>;
|
|
72
|
+
pricingModel: z.ZodEnum<{
|
|
73
|
+
readonly FREE: "Free";
|
|
74
|
+
readonly FIXED: "Fixed";
|
|
75
|
+
readonly PWYW: "Pay What You Want";
|
|
76
|
+
}>;
|
|
77
|
+
currency: z.ZodString;
|
|
78
|
+
price: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
|
|
79
|
+
suggestedPrice: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
|
|
80
|
+
discounts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
81
|
+
discountType: z.ZodEnum<{
|
|
82
|
+
readonly FIXED_AMOUNT: "Fixed Amount";
|
|
83
|
+
readonly PERCENTAGE: "Percentage";
|
|
84
|
+
}>;
|
|
85
|
+
amount: z.ZodNumber;
|
|
86
|
+
discountCode: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, z.core.$strip>>>;
|
|
88
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
89
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
90
|
+
deletedAt: z.ZodNullable<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
export type ProductCoverImageEntity = z.infer<typeof ProductCoverImageEntitySchema>;
|
|
93
|
+
export type ProductDeliveryFileEntity = z.infer<typeof ProductDeliveryFileEntitySchema>;
|
|
94
|
+
export type ProductDiscountEntity = z.infer<typeof ProductDiscountEntitySchema>;
|
|
95
|
+
export type CreateProductInputEntity = z.infer<typeof CreateProductInputSchema>;
|
|
96
|
+
export type ProductEntity = z.infer<typeof ProductEntitySchema>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProductEntitySchema = exports.CreateProductInputSchema = exports.ProductDiscountEntitySchema = exports.ProductDeliveryFileEntitySchema = exports.ProductCoverImageEntitySchema = void 0;
|
|
4
|
+
const zod_openapi_1 = require("@hono/zod-openapi");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
exports.ProductCoverImageEntitySchema = zod_openapi_1.z.object({
|
|
7
|
+
fileId: zod_openapi_1.z
|
|
8
|
+
.cuid2()
|
|
9
|
+
.openapi({ example: "f123e4567-e89b-12d3-a456-426614174000" }),
|
|
10
|
+
isThumbnail: zod_openapi_1.z.boolean().default(false),
|
|
11
|
+
order: zod_openapi_1.z.number().int().default(0),
|
|
12
|
+
});
|
|
13
|
+
exports.ProductDeliveryFileEntitySchema = zod_openapi_1.z.object({
|
|
14
|
+
fileId: zod_openapi_1.z
|
|
15
|
+
.cuid2()
|
|
16
|
+
.openapi({ example: "f987e6543-e89b-12d3-a456-426614174000" }),
|
|
17
|
+
order: zod_openapi_1.z.number().int().default(0),
|
|
18
|
+
});
|
|
19
|
+
exports.ProductDiscountEntitySchema = zod_openapi_1.z.object({
|
|
20
|
+
discountType: zod_openapi_1.z.enum(constants_1.DISCOUNT_TYPES),
|
|
21
|
+
amount: zod_openapi_1.z
|
|
22
|
+
.number()
|
|
23
|
+
.int("Amount must be a whole number")
|
|
24
|
+
.min(0, "Discount amount cannot be negative"),
|
|
25
|
+
discountCode: zod_openapi_1.z.string().optional(),
|
|
26
|
+
});
|
|
27
|
+
exports.CreateProductInputSchema = zod_openapi_1.z
|
|
28
|
+
.object({
|
|
29
|
+
title: zod_openapi_1.z.string().min(1, "Title is required").max(255),
|
|
30
|
+
description: zod_openapi_1.z.string().min(1, "Description is required"),
|
|
31
|
+
keyFeatures: zod_openapi_1.z.string(),
|
|
32
|
+
category: zod_openapi_1.z.string().min(1, "Category is required"),
|
|
33
|
+
subcategory: zod_openapi_1.z.string().optional(),
|
|
34
|
+
tags: zod_openapi_1.z
|
|
35
|
+
.array(zod_openapi_1.z.string())
|
|
36
|
+
.max(10, "Keep tags to a maximum of 10")
|
|
37
|
+
.default([]),
|
|
38
|
+
coverImages: zod_openapi_1.z
|
|
39
|
+
.array(exports.ProductCoverImageEntitySchema)
|
|
40
|
+
.min(1, "At least one cover image is required")
|
|
41
|
+
.max(3, "Maximum of 3 cover images allowed"),
|
|
42
|
+
productFiles: zod_openapi_1.z.array(exports.ProductDeliveryFileEntitySchema).default([]),
|
|
43
|
+
productLinks: zod_openapi_1.z
|
|
44
|
+
.array(zod_openapi_1.z.url().openapi({ example: "https://figma.com/file/..." }))
|
|
45
|
+
.default([]),
|
|
46
|
+
pricingModel: zod_openapi_1.z.enum(constants_1.PRICING_MODELS).default(constants_1.PRICING_MODELS.FIXED),
|
|
47
|
+
currency: zod_openapi_1.z.string().default("USD").openapi({ example: "USD" }),
|
|
48
|
+
price: zod_openapi_1.z.number().int("Must be in cents").min(0).optional(),
|
|
49
|
+
suggestedPrice: zod_openapi_1.z.number().int("Must be in cents").min(0).optional(),
|
|
50
|
+
discounts: zod_openapi_1.z.array(exports.ProductDiscountEntitySchema).default([]),
|
|
51
|
+
})
|
|
52
|
+
.superRefine((data, ctx) => {
|
|
53
|
+
if (data.pricingModel === constants_1.PRICING_MODELS.FIXED &&
|
|
54
|
+
(!data.price || data.price <= 0)) {
|
|
55
|
+
ctx.addIssue({
|
|
56
|
+
code: "custom",
|
|
57
|
+
message: "Fixed pricing requires a price strictly greater than 0.",
|
|
58
|
+
path: ["price"],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (data.pricingModel === constants_1.PRICING_MODELS.PWYW) {
|
|
62
|
+
if (data.suggestedPrice !== undefined && data.price !== undefined) {
|
|
63
|
+
if (data.suggestedPrice < data.price) {
|
|
64
|
+
ctx.addIssue({
|
|
65
|
+
code: "custom",
|
|
66
|
+
message: "Suggested price cannot be lower than the minimum price.",
|
|
67
|
+
path: ["suggestedPrice"],
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (data.pricingModel === constants_1.PRICING_MODELS.FREE &&
|
|
73
|
+
data.price &&
|
|
74
|
+
data.price > 0) {
|
|
75
|
+
ctx.addIssue({
|
|
76
|
+
code: "custom",
|
|
77
|
+
message: "Free products cannot have a price greater than 0.",
|
|
78
|
+
path: ["price"],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (data.productFiles.length === 0 && data.productLinks.length === 0) {
|
|
82
|
+
ctx.addIssue({
|
|
83
|
+
code: "custom",
|
|
84
|
+
message: "You must provide at least one product file or a link for the buyer to receive.",
|
|
85
|
+
path: ["productFiles"],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const thumbnails = data.coverImages.filter((img) => img.isThumbnail);
|
|
89
|
+
if (thumbnails.length !== 1) {
|
|
90
|
+
ctx.addIssue({
|
|
91
|
+
code: "custom",
|
|
92
|
+
message: "Exactly one cover image must be set as the thumbnail.",
|
|
93
|
+
path: ["coverImages"],
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
exports.ProductEntitySchema = zod_openapi_1.z
|
|
98
|
+
.object({
|
|
99
|
+
id: zod_openapi_1.z.cuid2(),
|
|
100
|
+
userId: zod_openapi_1.z.cuid2().openapi({ description: "ID of the creator/seller" }),
|
|
101
|
+
title: zod_openapi_1.z.string(),
|
|
102
|
+
description: zod_openapi_1.z.string(),
|
|
103
|
+
keyFeatures: zod_openapi_1.z.string(),
|
|
104
|
+
category: zod_openapi_1.z.string(),
|
|
105
|
+
subcategory: zod_openapi_1.z.string().optional().nullable(),
|
|
106
|
+
tags: zod_openapi_1.z.array(zod_openapi_1.z.string()),
|
|
107
|
+
coverImages: zod_openapi_1.z.array(exports.ProductCoverImageEntitySchema).default([]),
|
|
108
|
+
productFiles: zod_openapi_1.z.array(exports.ProductDeliveryFileEntitySchema).default([]),
|
|
109
|
+
productLinks: zod_openapi_1.z.array(zod_openapi_1.z.url()).default([]),
|
|
110
|
+
pricingModel: zod_openapi_1.z.enum(constants_1.PRICING_MODELS),
|
|
111
|
+
currency: zod_openapi_1.z.string(),
|
|
112
|
+
price: zod_openapi_1.z.number().int().optional().nullable(),
|
|
113
|
+
suggestedPrice: zod_openapi_1.z.number().int().optional().nullable(),
|
|
114
|
+
discounts: zod_openapi_1.z.array(exports.ProductDiscountEntitySchema).default([]),
|
|
115
|
+
createdAt: zod_openapi_1.z.coerce.date(),
|
|
116
|
+
updatedAt: zod_openapi_1.z.coerce.date(),
|
|
117
|
+
deletedAt: zod_openapi_1.z.coerce.date().optional().nullable(),
|
|
118
|
+
})
|
|
119
|
+
.openapi({ title: "ProductEntity" });
|
package/dist/schemas/seller.d.ts
CHANGED
|
@@ -41,3 +41,42 @@ export declare const UpdateSellerEntitySchema: z.ZodObject<{
|
|
|
41
41
|
}>>;
|
|
42
42
|
}, z.core.$strip>;
|
|
43
43
|
export type UpdateSellerInput = z.infer<typeof UpdateSellerEntitySchema>;
|
|
44
|
+
export declare const SellerProfileSchema: z.ZodObject<{
|
|
45
|
+
id: z.ZodCUID2;
|
|
46
|
+
businessName: z.ZodString;
|
|
47
|
+
countryOfOperation: z.ZodEnum<{
|
|
48
|
+
readonly NG: "NG";
|
|
49
|
+
readonly GB: "GB";
|
|
50
|
+
}>;
|
|
51
|
+
stripeConnectId: z.ZodNullable<z.ZodString>;
|
|
52
|
+
paystackSubaccountCode: z.ZodNullable<z.ZodString>;
|
|
53
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
54
|
+
readonly ACTIVE: "ACTIVE";
|
|
55
|
+
readonly PENDING: "PENDING";
|
|
56
|
+
readonly SUSPENDED: "SUSPENDED";
|
|
57
|
+
}>>;
|
|
58
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
59
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
60
|
+
payoutMethods: z.ZodArray<z.ZodObject<{
|
|
61
|
+
id: z.ZodCUID2;
|
|
62
|
+
sellerId: z.ZodCUID2;
|
|
63
|
+
provider: z.ZodEnum<{
|
|
64
|
+
readonly PAYSTACK: "PAYSTACK";
|
|
65
|
+
readonly STRIPE: "STRIPE";
|
|
66
|
+
}>;
|
|
67
|
+
currency: z.ZodString;
|
|
68
|
+
bankName: z.ZodString;
|
|
69
|
+
accountLast4: z.ZodString;
|
|
70
|
+
accountName: z.ZodString;
|
|
71
|
+
externalBankId: z.ZodNullable<z.ZodString>;
|
|
72
|
+
isDefault: z.ZodBoolean;
|
|
73
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
74
|
+
readonly VERIFIED: "VERIFIED";
|
|
75
|
+
readonly PENDING: "PENDING";
|
|
76
|
+
readonly REJECTED: "REJECTED";
|
|
77
|
+
}>>;
|
|
78
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
79
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
80
|
+
}, z.core.$strip>>;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
export type SellerProfile = z.infer<typeof SellerProfileSchema>;
|
package/dist/schemas/seller.js
CHANGED
|
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.UpdateSellerEntitySchema = exports.CreateSellerEntityInputSchema = exports.SellerEntitySchema = void 0;
|
|
6
|
+
exports.SellerProfileSchema = exports.UpdateSellerEntitySchema = exports.CreateSellerEntityInputSchema = exports.SellerEntitySchema = void 0;
|
|
7
7
|
const zod_1 = __importDefault(require("zod"));
|
|
8
8
|
const constants_1 = require("../constants");
|
|
9
|
+
const payout_method_1 = require("./payout-method");
|
|
9
10
|
exports.SellerEntitySchema = zod_1.default.object({
|
|
10
11
|
id: zod_1.default.cuid2(),
|
|
11
12
|
businessName: zod_1.default.string(), // Kept here for the app to consume!
|
|
@@ -31,3 +32,6 @@ exports.UpdateSellerEntitySchema = zod_1.default
|
|
|
31
32
|
status: zod_1.default.enum(constants_1.SELLER_STATUS),
|
|
32
33
|
})
|
|
33
34
|
.partial();
|
|
35
|
+
exports.SellerProfileSchema = exports.SellerEntitySchema.extend({
|
|
36
|
+
payoutMethods: zod_1.default.array(payout_method_1.PayoutMethodEntitySchema),
|
|
37
|
+
});
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -318,6 +318,17 @@ export const GATEWAY_PROVIDER = {
|
|
|
318
318
|
STRIPE: "STRIPE",
|
|
319
319
|
} as const;
|
|
320
320
|
|
|
321
|
+
export const PRICING_MODELS = {
|
|
322
|
+
FREE: "Free",
|
|
323
|
+
FIXED: "Fixed",
|
|
324
|
+
PWYW: "Pay What You Want",
|
|
325
|
+
} as const;
|
|
326
|
+
|
|
327
|
+
export const DISCOUNT_TYPES = {
|
|
328
|
+
FIXED_AMOUNT: "Fixed Amount",
|
|
329
|
+
PERCENTAGE: "Percentage",
|
|
330
|
+
} as const;
|
|
331
|
+
|
|
321
332
|
export type SignalInterestType =
|
|
322
333
|
(typeof SIGNAL_INTEREST_TYPES)[keyof typeof SIGNAL_INTEREST_TYPES];
|
|
323
334
|
export type SignalStatus = (typeof SIGNAL_STATUS)[keyof typeof SIGNAL_STATUS];
|
|
@@ -373,6 +384,8 @@ export type GatewayProvider =
|
|
|
373
384
|
(typeof GATEWAY_PROVIDER)[keyof typeof GATEWAY_PROVIDER];
|
|
374
385
|
export type PaymentMethodStatus =
|
|
375
386
|
(typeof PAYMENT_METHOD_STATUS)[keyof typeof PAYMENT_METHOD_STATUS];
|
|
387
|
+
export type PricingModel = (typeof PRICING_MODELS)[keyof typeof PRICING_MODELS];
|
|
388
|
+
export type DiscountType = (typeof DISCOUNT_TYPES)[keyof typeof DISCOUNT_TYPES];
|
|
376
389
|
export const API_ROUTES = {
|
|
377
390
|
healthCheck: "/health",
|
|
378
391
|
username: {
|
package/src/schemas/index.ts
CHANGED
package/src/schemas/post.ts
CHANGED
|
@@ -33,10 +33,7 @@ export const PostEntitySchema = z.object({
|
|
|
33
33
|
.openapi({
|
|
34
34
|
example: [{ name: "javascript", id: 101 }],
|
|
35
35
|
}),
|
|
36
|
-
badge: z
|
|
37
|
-
.enum(POST_BADGE_TYPES)
|
|
38
|
-
.optional()
|
|
39
|
-
.openapi({ example: "FEATURED" }),
|
|
36
|
+
badge: z.enum(POST_BADGE_TYPES).optional().openapi({ example: "FEATURED" }),
|
|
40
37
|
userId: z
|
|
41
38
|
.cuid2()
|
|
42
39
|
.openapi({ description: "User id", example: "ckj1a2b3c0000def" }),
|
|
@@ -44,10 +41,7 @@ export const PostEntitySchema = z.object({
|
|
|
44
41
|
.string()
|
|
45
42
|
.optional()
|
|
46
43
|
.openapi({ description: "Username", example: "dev_guru" }),
|
|
47
|
-
creatorFullName: z
|
|
48
|
-
.string()
|
|
49
|
-
.optional()
|
|
50
|
-
.openapi({ example: "Jane Doe" }),
|
|
44
|
+
creatorFullName: z.string().optional().openapi({ example: "Jane Doe" }),
|
|
51
45
|
creatorImageUrl: z
|
|
52
46
|
.cuid2()
|
|
53
47
|
.optional()
|
|
@@ -72,8 +66,7 @@ export const PostEntitySchema = z.object({
|
|
|
72
66
|
example: "PROJECT",
|
|
73
67
|
}),
|
|
74
68
|
|
|
75
|
-
createdAt: z
|
|
76
|
-
.coerce
|
|
69
|
+
createdAt: z.coerce
|
|
77
70
|
.date()
|
|
78
71
|
.optional()
|
|
79
72
|
.openapi({ example: "2026-03-11T14:43:09Z" }),
|
|
@@ -107,14 +100,17 @@ export const PostFileEntitySchema = z
|
|
|
107
100
|
.object({
|
|
108
101
|
id: z
|
|
109
102
|
.cuid2()
|
|
110
|
-
.openapi({
|
|
103
|
+
.openapi({
|
|
104
|
+
description: "CUID2 of the project file record.",
|
|
105
|
+
example: "cxy1a2b3c0000qwe",
|
|
106
|
+
}),
|
|
111
107
|
postId: z.cuid2().openapi({
|
|
112
108
|
description: "CUID2 of the post this file belongs to.",
|
|
113
109
|
example: "ckj1a2b3c0000xyz",
|
|
114
110
|
}),
|
|
115
|
-
fileId: z.cuid2().openapi({
|
|
116
|
-
description: "CUID2 of the linked file.",
|
|
117
|
-
example: "cvb1a2b3c0000rty"
|
|
111
|
+
fileId: z.cuid2().openapi({
|
|
112
|
+
description: "CUID2 of the linked file.",
|
|
113
|
+
example: "cvb1a2b3c0000rty",
|
|
118
114
|
}),
|
|
119
115
|
order: z.number().int().openapi({
|
|
120
116
|
description: "Order index of the file in the project.",
|
|
@@ -134,7 +130,7 @@ export const PostWithFilesEntitySchema = PostEntitySchema.extend({
|
|
|
134
130
|
}),
|
|
135
131
|
)
|
|
136
132
|
.optional()
|
|
137
|
-
.openapi({
|
|
133
|
+
.openapi({
|
|
138
134
|
description: "Files associated with the project.",
|
|
139
135
|
example: [
|
|
140
136
|
{
|
|
@@ -142,9 +138,9 @@ export const PostWithFilesEntitySchema = PostEntitySchema.extend({
|
|
|
142
138
|
postId: "ckj1a2b3c0000xyz",
|
|
143
139
|
fileId: "cvb1a2b3c0000rty",
|
|
144
140
|
order: 1,
|
|
145
|
-
url: "https://cdn.example.com/image.png"
|
|
146
|
-
}
|
|
147
|
-
]
|
|
141
|
+
url: "https://cdn.example.com/image.png",
|
|
142
|
+
},
|
|
143
|
+
],
|
|
148
144
|
}),
|
|
149
145
|
});
|
|
150
146
|
|
|
@@ -185,19 +181,26 @@ export const CreatePostInputSchema = z.object({
|
|
|
185
181
|
)
|
|
186
182
|
.max(5, { message: "Cannot attach more than 5 files" })
|
|
187
183
|
.optional()
|
|
188
|
-
.openapi({
|
|
189
|
-
example: [{ fileId: "cvb1a2b3c0000rty", order: 1 }]
|
|
184
|
+
.openapi({
|
|
185
|
+
example: [{ fileId: "cvb1a2b3c0000rty", order: 1 }],
|
|
190
186
|
}),
|
|
191
187
|
|
|
192
188
|
tags: z
|
|
193
|
-
.array(
|
|
189
|
+
.array(
|
|
190
|
+
z
|
|
191
|
+
.string()
|
|
192
|
+
.min(1, { message: "Tag cannot be empty" })
|
|
193
|
+
.openapi({ example: "react" }),
|
|
194
|
+
)
|
|
194
195
|
.max(3, { message: "Cannot add more than 3 tags" })
|
|
195
196
|
.optional()
|
|
196
197
|
.openapi({ example: ["react", "frontend"] }),
|
|
197
198
|
badge: z.enum(POST_BADGE_TYPES).optional().openapi({ example: "TRENDING" }),
|
|
198
199
|
linkMeta: z
|
|
199
200
|
.object({
|
|
200
|
-
url: z
|
|
201
|
+
url: z
|
|
202
|
+
.url({ message: "Invalid URL format" })
|
|
203
|
+
.openapi({ example: "https://example.com" }),
|
|
201
204
|
title: z
|
|
202
205
|
.string()
|
|
203
206
|
.max(200, { message: "Title cannot exceed 200 characters" })
|
|
@@ -210,7 +213,10 @@ export const CreatePostInputSchema = z.object({
|
|
|
210
213
|
})
|
|
211
214
|
.optional()
|
|
212
215
|
.openapi({ example: "This is an example link" }),
|
|
213
|
-
image: z
|
|
216
|
+
image: z
|
|
217
|
+
.url({ message: "Invalid image URL" })
|
|
218
|
+
.optional()
|
|
219
|
+
.openapi({ example: "https://example.com/preview.jpg" }),
|
|
214
220
|
})
|
|
215
221
|
.optional()
|
|
216
222
|
.openapi({
|
|
@@ -226,8 +232,8 @@ export const CreatePostInputSchema = z.object({
|
|
|
226
232
|
|
|
227
233
|
export const CreatePostOutputSchema = PostEntitySchema;
|
|
228
234
|
export const GetPostOutputSchema = PostWithFilesEntitySchema;
|
|
229
|
-
export const PostIdSchema = z.object({
|
|
230
|
-
postId: z.cuid2().openapi({ example: "ckj1a2b3c0000xyz" })
|
|
235
|
+
export const PostIdSchema = z.object({
|
|
236
|
+
postId: z.cuid2().openapi({ example: "ckj1a2b3c0000xyz" }),
|
|
231
237
|
});
|
|
232
238
|
|
|
233
239
|
export const MinimalPostSchema = PostEntitySchema.pick({
|
|
@@ -237,18 +243,24 @@ export const MinimalPostSchema = PostEntitySchema.pick({
|
|
|
237
243
|
});
|
|
238
244
|
|
|
239
245
|
export const PostWithLikesEntitySchema = MinimalPostSchema.extend({
|
|
240
|
-
likes: z
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
likes: z
|
|
247
|
+
.array(
|
|
248
|
+
ActivitySchema.extend({
|
|
249
|
+
followsYou: z.boolean().optional().openapi({ example: true }),
|
|
250
|
+
isFollowing: z.boolean().optional().openapi({ example: false }),
|
|
251
|
+
}),
|
|
252
|
+
)
|
|
253
|
+
.openapi({ example: [] }),
|
|
246
254
|
}).openapi({
|
|
247
255
|
title: "PostWithPostLikesEntity",
|
|
248
256
|
});
|
|
249
257
|
|
|
250
258
|
export const GetPostWithLikesOutputSchema = PostWithLikesEntitySchema.extend({
|
|
251
|
-
nextCursor: z
|
|
259
|
+
nextCursor: z
|
|
260
|
+
.string()
|
|
261
|
+
.optional()
|
|
262
|
+
.nullable()
|
|
263
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
252
264
|
});
|
|
253
265
|
|
|
254
266
|
export const PostWithCommentsEntitySchema = MinimalPostSchema.extend({
|
|
@@ -259,7 +271,11 @@ export const PostWithCommentsEntitySchema = MinimalPostSchema.extend({
|
|
|
259
271
|
|
|
260
272
|
export const GetPostWithCommentsOutputSchema =
|
|
261
273
|
PostWithCommentsEntitySchema.extend({
|
|
262
|
-
nextCursor: z
|
|
274
|
+
nextCursor: z
|
|
275
|
+
.string()
|
|
276
|
+
.optional()
|
|
277
|
+
.nullable()
|
|
278
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
263
279
|
});
|
|
264
280
|
|
|
265
281
|
export const PostWithBookmarksEntitySchema = MinimalPostSchema.extend({
|
|
@@ -274,14 +290,23 @@ export const GetPostWithBookmarksOutputSchema =
|
|
|
274
290
|
});
|
|
275
291
|
|
|
276
292
|
export const LinkPreviewInputSchema = z.object({
|
|
277
|
-
url: z.url().openapi({ example: "https://example.com/article" }),
|
|
293
|
+
url: z.url().openapi({ example: "https://example.com/article" }),
|
|
278
294
|
});
|
|
279
295
|
|
|
280
296
|
export const LinkPreviewOutputSchema = z.object({
|
|
281
297
|
title: z.string().openapi({ example: "Great Article" }),
|
|
282
|
-
description: z
|
|
283
|
-
|
|
284
|
-
|
|
298
|
+
description: z
|
|
299
|
+
.string()
|
|
300
|
+
.optional()
|
|
301
|
+
.openapi({ example: "A detailed breakdown of the topic." }),
|
|
302
|
+
image: z
|
|
303
|
+
.string()
|
|
304
|
+
.optional()
|
|
305
|
+
.openapi({ example: "https://example.com/hero.jpg" }),
|
|
306
|
+
url: z
|
|
307
|
+
.string()
|
|
308
|
+
.optional()
|
|
309
|
+
.openapi({ example: "https://example.com/article" }),
|
|
285
310
|
});
|
|
286
311
|
|
|
287
312
|
export const FeedPostEntitySchema = PostWithFilesEntitySchema.extend({
|
|
@@ -299,7 +324,11 @@ export const GetFeedInputSchema = z.object({
|
|
|
299
324
|
|
|
300
325
|
export const GetFeedOutputSchema = z.object({
|
|
301
326
|
feed: z.array(FeedPostEntitySchema).openapi({ example: [] }),
|
|
302
|
-
nextCursor: z
|
|
327
|
+
nextCursor: z
|
|
328
|
+
.string()
|
|
329
|
+
.optional()
|
|
330
|
+
.nullable()
|
|
331
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
303
332
|
});
|
|
304
333
|
|
|
305
334
|
export const SearchPostInputSchema = z.object({
|
|
@@ -313,7 +342,11 @@ export const SearchPostInputSchema = z.object({
|
|
|
313
342
|
|
|
314
343
|
export const SearchPostOutputSchema = z.object({
|
|
315
344
|
posts: z.array(FeedPostEntitySchema).openapi({ example: [] }),
|
|
316
|
-
nextCursor: z
|
|
345
|
+
nextCursor: z
|
|
346
|
+
.string()
|
|
347
|
+
.optional()
|
|
348
|
+
.nullable()
|
|
349
|
+
.openapi({ example: "ckj1a2b3c0000nxt" }),
|
|
317
350
|
});
|
|
318
351
|
|
|
319
352
|
export const ReportPostInputSchema = z.object({
|
|
@@ -341,8 +374,12 @@ export const PostAnalyticsOutputSchema = z.object({
|
|
|
341
374
|
comments: z.number().openapi({ example: 34 }),
|
|
342
375
|
linkCopied: z.number().openapi({ example: 12 }),
|
|
343
376
|
bookmarks: z.number().openapi({ example: 56 }),
|
|
344
|
-
tagsClicked: z
|
|
345
|
-
|
|
377
|
+
tagsClicked: z
|
|
378
|
+
.array(AnalyticsChartItemSchema)
|
|
379
|
+
.openapi({ example: [{ x: "javascript", y: 25 }] }),
|
|
380
|
+
platformShares: z
|
|
381
|
+
.array(AnalyticsChartItemSchema)
|
|
382
|
+
.openapi({ example: [{ x: "Twitter", y: 10 }] }),
|
|
346
383
|
}),
|
|
347
384
|
behavior: z.object({
|
|
348
385
|
viralityScore: z.number().openapi({ example: 8.5 }),
|
|
@@ -359,44 +396,65 @@ export const PostAnalyticsOutputSchema = z.object({
|
|
|
359
396
|
}),
|
|
360
397
|
});
|
|
361
398
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
399
|
+
export const PostSearchDocumentSchema = z
|
|
400
|
+
.object({
|
|
401
|
+
id: z.cuid2().openapi({ example: "ckj1a2b3c0000doc" }),
|
|
402
|
+
userId: z.cuid2().openapi({ example: "ckj1a2b3c0000usr" }),
|
|
403
|
+
parentId: z.cuid2().nullable().openapi({ example: "ckj1a2b3c0000prt" }),
|
|
404
|
+
parentType: z.enum(ACTIVITY_PARENT_TYPES).openapi({ example: "POST" }),
|
|
405
|
+
creatorUsername: z.string().nullable().openapi({ example: "tech_lead" }),
|
|
406
|
+
creatorFullName: z.string().nullable().openapi({ example: "Alex Smith" }),
|
|
407
|
+
creatorImageUrl: z
|
|
408
|
+
.cuid2()
|
|
409
|
+
.nullable()
|
|
410
|
+
.openapi({ example: "clm1a2b3c0000pic" }),
|
|
411
|
+
tagIds: z.array(z.number()).openapi({ example: [101, 102] }),
|
|
412
|
+
tagNames: z.array(z.string()).openapi({ example: ["react", "typescript"] }),
|
|
413
|
+
badge: z.enum(POST_BADGE_TYPES).nullable().openapi({ example: "TRENDING" }),
|
|
414
|
+
postType: z.enum(POST_TYPES).openapi({ example: "PROJECT" }),
|
|
415
|
+
content: z
|
|
416
|
+
.string()
|
|
417
|
+
.nullable()
|
|
418
|
+
.openapi({ example: "Here is my latest open source tool." }),
|
|
419
|
+
linkTitle: z.string().nullable().openapi({ example: "GitHub Repo" }),
|
|
420
|
+
linkDescription: z
|
|
421
|
+
.string()
|
|
422
|
+
.nullable()
|
|
423
|
+
.openapi({ example: "A fast, modern build system." }),
|
|
424
|
+
linkUrl: z
|
|
425
|
+
.url()
|
|
426
|
+
.nullable()
|
|
427
|
+
.openapi({ example: "https://github.com/project" }),
|
|
428
|
+
linkImage: z
|
|
429
|
+
.url()
|
|
430
|
+
.nullable()
|
|
431
|
+
.openapi({ example: "https://github.com/image.png" }),
|
|
432
|
+
postFiles: z
|
|
433
|
+
.array(
|
|
434
|
+
PostFileEntitySchema.extend({
|
|
435
|
+
url: z
|
|
436
|
+
.url()
|
|
437
|
+
.openapi({ example: "https://cdn.example.com/file1.png" }),
|
|
438
|
+
}),
|
|
439
|
+
)
|
|
440
|
+
.nullable()
|
|
441
|
+
.openapi({
|
|
442
|
+
example: [
|
|
443
|
+
{
|
|
444
|
+
id: "cxy1a2b3c0000qwe",
|
|
445
|
+
postId: "ckj1a2b3c0000doc",
|
|
446
|
+
fileId: "cvb1a2b3c0000rty",
|
|
447
|
+
order: 1,
|
|
448
|
+
url: "https://cdn.example.com/file1.png",
|
|
449
|
+
},
|
|
450
|
+
],
|
|
384
451
|
}),
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
example:
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
url: "https://cdn.example.com/file1.png",
|
|
395
|
-
},
|
|
396
|
-
],
|
|
397
|
-
}),
|
|
398
|
-
createdAt: z.string().nullable().openapi({ example: "2026-03-11T14:43:09.000Z" }),
|
|
399
|
-
}).openapi({
|
|
400
|
-
title: "Post Search Document",
|
|
401
|
-
description: "Flattened schema used for indexing posts in search engines.",
|
|
402
|
-
});
|
|
452
|
+
createdAt: z
|
|
453
|
+
.string()
|
|
454
|
+
.nullable()
|
|
455
|
+
.openapi({ example: "2026-03-11T14:43:09.000Z" }),
|
|
456
|
+
})
|
|
457
|
+
.openapi({
|
|
458
|
+
title: "Post Search Document",
|
|
459
|
+
description: "Flattened schema used for indexing posts in search engines.",
|
|
460
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
import { DISCOUNT_TYPES, PRICING_MODELS } from "../constants";
|
|
3
|
+
|
|
4
|
+
export const ProductCoverImageEntitySchema = z.object({
|
|
5
|
+
fileId: z
|
|
6
|
+
.cuid2()
|
|
7
|
+
.openapi({ example: "f123e4567-e89b-12d3-a456-426614174000" }),
|
|
8
|
+
isThumbnail: z.boolean().default(false),
|
|
9
|
+
order: z.number().int().default(0),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const ProductDeliveryFileEntitySchema = z.object({
|
|
13
|
+
fileId: z
|
|
14
|
+
.cuid2()
|
|
15
|
+
.openapi({ example: "f987e6543-e89b-12d3-a456-426614174000" }),
|
|
16
|
+
order: z.number().int().default(0),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const ProductDiscountEntitySchema = z.object({
|
|
20
|
+
discountType: z.enum(DISCOUNT_TYPES),
|
|
21
|
+
|
|
22
|
+
amount: z
|
|
23
|
+
.number()
|
|
24
|
+
.int("Amount must be a whole number")
|
|
25
|
+
.min(0, "Discount amount cannot be negative"),
|
|
26
|
+
discountCode: z.string().optional(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const CreateProductInputSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
title: z.string().min(1, "Title is required").max(255),
|
|
32
|
+
description: z.string().min(1, "Description is required"),
|
|
33
|
+
keyFeatures: z.string(),
|
|
34
|
+
|
|
35
|
+
category: z.string().min(1, "Category is required"),
|
|
36
|
+
subcategory: z.string().optional(),
|
|
37
|
+
tags: z
|
|
38
|
+
.array(z.string())
|
|
39
|
+
.max(10, "Keep tags to a maximum of 10")
|
|
40
|
+
.default([]),
|
|
41
|
+
|
|
42
|
+
coverImages: z
|
|
43
|
+
.array(ProductCoverImageEntitySchema)
|
|
44
|
+
.min(1, "At least one cover image is required")
|
|
45
|
+
.max(3, "Maximum of 3 cover images allowed"),
|
|
46
|
+
|
|
47
|
+
productFiles: z.array(ProductDeliveryFileEntitySchema).default([]),
|
|
48
|
+
productLinks: z
|
|
49
|
+
.array(z.url().openapi({ example: "https://figma.com/file/..." }))
|
|
50
|
+
.default([]),
|
|
51
|
+
|
|
52
|
+
pricingModel: z.enum(PRICING_MODELS).default(PRICING_MODELS.FIXED),
|
|
53
|
+
currency: z.string().default("USD").openapi({ example: "USD" }),
|
|
54
|
+
|
|
55
|
+
price: z.number().int("Must be in cents").min(0).optional(),
|
|
56
|
+
suggestedPrice: z.number().int("Must be in cents").min(0).optional(),
|
|
57
|
+
|
|
58
|
+
discounts: z.array(ProductDiscountEntitySchema).default([]),
|
|
59
|
+
})
|
|
60
|
+
.superRefine((data, ctx) => {
|
|
61
|
+
if (
|
|
62
|
+
data.pricingModel === PRICING_MODELS.FIXED &&
|
|
63
|
+
(!data.price || data.price <= 0)
|
|
64
|
+
) {
|
|
65
|
+
ctx.addIssue({
|
|
66
|
+
code: "custom",
|
|
67
|
+
message: "Fixed pricing requires a price strictly greater than 0.",
|
|
68
|
+
path: ["price"],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (data.pricingModel === PRICING_MODELS.PWYW) {
|
|
73
|
+
if (data.suggestedPrice !== undefined && data.price !== undefined) {
|
|
74
|
+
if (data.suggestedPrice < data.price) {
|
|
75
|
+
ctx.addIssue({
|
|
76
|
+
code: "custom",
|
|
77
|
+
message: "Suggested price cannot be lower than the minimum price.",
|
|
78
|
+
path: ["suggestedPrice"],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
data.pricingModel === PRICING_MODELS.FREE &&
|
|
86
|
+
data.price &&
|
|
87
|
+
data.price > 0
|
|
88
|
+
) {
|
|
89
|
+
ctx.addIssue({
|
|
90
|
+
code: "custom",
|
|
91
|
+
message: "Free products cannot have a price greater than 0.",
|
|
92
|
+
path: ["price"],
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (data.productFiles.length === 0 && data.productLinks.length === 0) {
|
|
97
|
+
ctx.addIssue({
|
|
98
|
+
code: "custom",
|
|
99
|
+
message:
|
|
100
|
+
"You must provide at least one product file or a link for the buyer to receive.",
|
|
101
|
+
path: ["productFiles"],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const thumbnails = data.coverImages.filter((img) => img.isThumbnail);
|
|
106
|
+
if (thumbnails.length !== 1) {
|
|
107
|
+
ctx.addIssue({
|
|
108
|
+
code: "custom",
|
|
109
|
+
message: "Exactly one cover image must be set as the thumbnail.",
|
|
110
|
+
path: ["coverImages"],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export const ProductEntitySchema = z
|
|
116
|
+
.object({
|
|
117
|
+
id: z.cuid2(),
|
|
118
|
+
userId: z.cuid2().openapi({ description: "ID of the creator/seller" }),
|
|
119
|
+
|
|
120
|
+
title: z.string(),
|
|
121
|
+
description: z.string(),
|
|
122
|
+
keyFeatures: z.string(),
|
|
123
|
+
|
|
124
|
+
category: z.string(),
|
|
125
|
+
subcategory: z.string().optional().nullable(),
|
|
126
|
+
tags: z.array(z.string()),
|
|
127
|
+
|
|
128
|
+
coverImages: z.array(ProductCoverImageEntitySchema).default([]),
|
|
129
|
+
productFiles: z.array(ProductDeliveryFileEntitySchema).default([]),
|
|
130
|
+
productLinks: z.array(z.url()).default([]),
|
|
131
|
+
|
|
132
|
+
pricingModel: z.enum(PRICING_MODELS),
|
|
133
|
+
currency: z.string(),
|
|
134
|
+
price: z.number().int().optional().nullable(),
|
|
135
|
+
suggestedPrice: z.number().int().optional().nullable(),
|
|
136
|
+
|
|
137
|
+
discounts: z.array(ProductDiscountEntitySchema).default([]),
|
|
138
|
+
|
|
139
|
+
createdAt: z.coerce.date(),
|
|
140
|
+
updatedAt: z.coerce.date(),
|
|
141
|
+
deletedAt: z.coerce.date().optional().nullable(),
|
|
142
|
+
})
|
|
143
|
+
.openapi({ title: "ProductEntity" });
|
|
144
|
+
|
|
145
|
+
export type ProductCoverImageEntity = z.infer<
|
|
146
|
+
typeof ProductCoverImageEntitySchema
|
|
147
|
+
>;
|
|
148
|
+
export type ProductDeliveryFileEntity = z.infer<
|
|
149
|
+
typeof ProductDeliveryFileEntitySchema
|
|
150
|
+
>;
|
|
151
|
+
export type ProductDiscountEntity = z.infer<typeof ProductDiscountEntitySchema>;
|
|
152
|
+
export type CreateProductInputEntity = z.infer<typeof CreateProductInputSchema>;
|
|
153
|
+
export type ProductEntity = z.infer<typeof ProductEntitySchema>;
|
package/src/schemas/seller.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
2
|
import { COUNTRY_OF_OPERATION, SELLER_STATUS } from "../constants";
|
|
3
|
+
import { PayoutMethodEntitySchema } from "./payout-method";
|
|
3
4
|
|
|
4
5
|
export const SellerEntitySchema = z.object({
|
|
5
6
|
id: z.cuid2(),
|
|
@@ -31,3 +32,9 @@ export const UpdateSellerEntitySchema = z
|
|
|
31
32
|
})
|
|
32
33
|
.partial();
|
|
33
34
|
export type UpdateSellerInput = z.infer<typeof UpdateSellerEntitySchema>;
|
|
35
|
+
|
|
36
|
+
export const SellerProfileSchema = SellerEntitySchema.extend({
|
|
37
|
+
payoutMethods: z.array(PayoutMethodEntitySchema),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export type SellerProfile = z.infer<typeof SellerProfileSchema>;
|