@mac777/project-pinecone-schema 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/events/events.constants.d.ts +1 -8
  2. package/dist/events/events.constants.js +1 -6
  3. package/dist/events/events.schema.d.ts +110 -55
  4. package/dist/events/events.type.d.ts +0 -8
  5. package/dist/events/utils/ticket.schema.d.ts +6 -3
  6. package/dist/events/utils/ticket.schema.js +2 -1
  7. package/package.json +2 -5
  8. package/src/auth/auth.constants.ts +9 -0
  9. package/src/auth/auth.schema.ts +65 -0
  10. package/src/auth/auth.type.ts +42 -0
  11. package/src/auth/index.ts +3 -0
  12. package/src/auth/utils/password.schema.ts +18 -0
  13. package/src/events/events.constants.ts +170 -0
  14. package/src/events/events.schema.ts +158 -0
  15. package/src/events/events.type.ts +51 -0
  16. package/src/events/events.utils.schema.ts +5 -0
  17. package/{dist/events/events.d.ts → src/events/index.ts} +4 -3
  18. package/src/events/utils/admin.schema.ts +77 -0
  19. package/src/events/utils/age.restriction.schema.ts +3 -0
  20. package/src/events/utils/document.schema.ts +8 -0
  21. package/src/events/utils/event.type.schema.ts +3 -0
  22. package/src/events/utils/media.schema.ts +36 -0
  23. package/src/events/utils/organizer.schema.ts +14 -0
  24. package/src/events/utils/schedule.schema.ts +10 -0
  25. package/src/events/utils/ticket.schema.ts +33 -0
  26. package/src/events/utils/venue.schema.ts +22 -0
  27. package/src/index.ts +5 -0
  28. package/src/media/index.ts +2 -0
  29. package/src/media/media.schema.ts +37 -0
  30. package/src/media/media.type.ts +18 -0
  31. package/src/media/utils/backblaze.schema.ts +8 -0
  32. package/src/media/utils/imagekit.schema.ts +20 -0
  33. package/src/orders/index.ts +6 -0
  34. package/src/orders/orders.schema.ts +106 -0
  35. package/src/orders/orders.type.ts +85 -0
  36. package/src/orders/payments.schema.ts +81 -0
  37. package/src/orders/payments.type.ts +87 -0
  38. package/src/orders/ticket.schema.ts +78 -0
  39. package/src/orders/ticket.type.ts +103 -0
  40. package/tsconfig.json +13 -0
  41. package/dist/auth.d.ts +0 -1
  42. package/dist/auth.js +0 -18
  43. package/dist/events/admin.schema.d.ts +0 -208
  44. package/dist/events/admin.schema.js +0 -70
  45. package/dist/events/age.restriction.schema.d.ts +0 -2
  46. package/dist/events/age.restriction.schema.js +0 -5
  47. package/dist/events/document.schema.d.ts +0 -17
  48. package/dist/events/document.schema.js +0 -10
  49. package/dist/events/event.schema.d.ts +0 -0
  50. package/dist/events/event.schema.js +0 -1
  51. package/dist/events/event.type.schema.d.ts +0 -2
  52. package/dist/events/event.type.schema.js +0 -5
  53. package/dist/events/events.constant.d.ts +0 -9
  54. package/dist/events/events.constant.js +0 -12
  55. package/dist/events/events.js +0 -19
  56. package/dist/events/media.schema.d.ts +0 -77
  57. package/dist/events/media.schema.js +0 -36
  58. package/dist/events/organizer.schema.d.ts +0 -55
  59. package/dist/events/organizer.schema.js +0 -15
  60. package/dist/events/schedule.schema.d.ts +0 -20
  61. package/dist/events/schedule.schema.js +0 -11
  62. package/dist/events/step.schema.d.ts +0 -0
  63. package/dist/events/step.schema.js +0 -1
  64. package/dist/events/ticket.schema.d.ts +0 -113
  65. package/dist/events/ticket.schema.js +0 -29
  66. package/dist/events/utils.schema.d.ts +0 -6
  67. package/dist/events/utils.schema.js +0 -22
  68. package/dist/events/venue.schema.d.ts +0 -75
  69. package/dist/events/venue.schema.js +0 -22
  70. package/dist/events.constant.d.ts +0 -9
  71. package/dist/events.constant.js +0 -12
  72. package/dist/events.constants.d.ts +0 -9
  73. package/dist/events.constants.js +0 -12
  74. package/dist/events.d.ts +0 -39
  75. package/dist/events.js +0 -2
  76. package/dist/events.schema.d.ts +0 -229
  77. package/dist/events.schema.js +0 -95
  78. package/dist/events.type.d.ts +0 -42
  79. package/dist/events.type.js +0 -2
  80. package/dist/events.utils.schema.d.ts +0 -6
  81. package/dist/events.utils.schema.js +0 -22
@@ -32,14 +32,6 @@ export type StepTicketsData = z.infer<typeof stepTicketsSchema>;
32
32
  export type StepReviewData = z.infer<typeof stepReviewSchema>;
33
33
  export type SubmitEventData = z.infer<typeof submitEventSchema>;
34
34
  export type DraftEventData = z.infer<typeof draftEventSchema>;
35
- export interface Event {
36
- id: string;
37
- title: string;
38
- location: string;
39
- category: string;
40
- date: string;
41
- image?: string;
42
- }
43
35
  export type GetEventData = z.infer<typeof getEventSchema>;
44
36
  export type ProtectedEventData = z.infer<typeof protectedEventSchema>;
45
37
  export type ClientGetEventData = z.infer<typeof clientGetEventSchema>;
@@ -30,7 +30,7 @@ export declare const limitsSchema: z.ZodObject<{
30
30
  maxPerOrder?: number | undefined;
31
31
  }>;
32
32
  export declare const displayTicketSchema: z.ZodObject<{
33
- id: z.ZodOptional<z.ZodString>;
33
+ _id: z.ZodOptional<z.ZodString>;
34
34
  name: z.ZodString;
35
35
  description: z.ZodOptional<z.ZodString>;
36
36
  price: z.ZodObject<{
@@ -66,6 +66,7 @@ export declare const displayTicketSchema: z.ZodObject<{
66
66
  }>>;
67
67
  remaining: z.ZodOptional<z.ZodNumber>;
68
68
  sold: z.ZodOptional<z.ZodNumber>;
69
+ reserved: z.ZodOptional<z.ZodNumber>;
69
70
  visibility: z.ZodOptional<z.ZodDefault<z.ZodEnum<["public", "hidden", "invite_only"]>>>;
70
71
  status: z.ZodOptional<z.ZodDefault<z.ZodEnum<["active", "inactive"]>>>;
71
72
  benefits: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -79,7 +80,7 @@ export declare const displayTicketSchema: z.ZodObject<{
79
80
  quantity: number;
80
81
  tier: "early_bird" | "regular" | "vip";
81
82
  status?: "active" | "inactive" | undefined;
82
- id?: string | undefined;
83
+ _id?: string | undefined;
83
84
  description?: string | undefined;
84
85
  salesWindow?: {
85
86
  startDate?: string | undefined;
@@ -91,6 +92,7 @@ export declare const displayTicketSchema: z.ZodObject<{
91
92
  } | undefined;
92
93
  remaining?: number | undefined;
93
94
  sold?: number | undefined;
95
+ reserved?: number | undefined;
94
96
  visibility?: "public" | "hidden" | "invite_only" | undefined;
95
97
  benefits?: string[] | undefined;
96
98
  }, {
@@ -101,7 +103,7 @@ export declare const displayTicketSchema: z.ZodObject<{
101
103
  };
102
104
  quantity: number;
103
105
  status?: "active" | "inactive" | undefined;
104
- id?: string | undefined;
106
+ _id?: string | undefined;
105
107
  description?: string | undefined;
106
108
  salesWindow?: {
107
109
  startDate?: string | undefined;
@@ -113,6 +115,7 @@ export declare const displayTicketSchema: z.ZodObject<{
113
115
  } | undefined;
114
116
  remaining?: number | undefined;
115
117
  sold?: number | undefined;
118
+ reserved?: number | undefined;
116
119
  visibility?: "public" | "hidden" | "invite_only" | undefined;
117
120
  benefits?: string[] | undefined;
118
121
  tier?: "early_bird" | "regular" | "vip" | undefined;
@@ -15,7 +15,7 @@ exports.limitsSchema = zod_1.z.object({
15
15
  maxPerOrder: zod_1.z.number({ required_error: 'Max per order must be a number' }).int('Max per order must be an integer').min(1, 'Max per order must be at least 1').default(10),
16
16
  });
17
17
  exports.displayTicketSchema = zod_1.z.object({
18
- id: zod_1.z.string().optional(),
18
+ _id: zod_1.z.string().optional(),
19
19
  name: zod_1.z.string({ required_error: 'Ticket name is required' }),
20
20
  description: zod_1.z.string().optional(),
21
21
  price: exports.priceSchema,
@@ -24,6 +24,7 @@ exports.displayTicketSchema = zod_1.z.object({
24
24
  limits: exports.limitsSchema.optional(),
25
25
  remaining: zod_1.z.number().optional(),
26
26
  sold: zod_1.z.number().optional(),
27
+ reserved: zod_1.z.number().optional(),
27
28
  visibility: zod_1.z.enum(['public', 'hidden', 'invite_only'], { required_error: 'Ticket visibility must be public, hidden, or invite_only' }).default('public').optional(),
28
29
  status: zod_1.z.enum(['active', 'inactive'], { required_error: 'Ticket status must be active or inactive' }).default('active').optional(),
29
30
  benefits: zod_1.z.array(zod_1.z.string(), { required_error: 'Benefits must be an array of strings' }).optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mac777/project-pinecone-schema",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -11,11 +11,8 @@
11
11
  "zod": "^3.22.4",
12
12
  "zxcvbn": "^4.4.2"
13
13
  },
14
- "files": ["dist"],
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
14
  "devDependencies": {
15
+ "@types/zxcvbn": "^4.4.5",
19
16
  "typescript": "^5.0.0"
20
17
  }
21
18
  }
@@ -0,0 +1,9 @@
1
+ // Password strength requirements
2
+ export const MIN_PASSWORD_LENGTH = 8;
3
+ export const MAX_PASSWORD_LENGTH = 128;
4
+ export const MIN_FIRST_NAME_LENGTH = 3;
5
+ export const MAX_FIRST_NAME_LENGTH = 20;
6
+ export const MIN_LAST_NAME_LENGTH = 3;
7
+ export const MAX_LAST_NAME_LENGTH = 20;
8
+ export const MIN_ORGANIZATION_NAME_LENGTH = 3;
9
+ export const MAX_ORGANIZATION_NAME_LENGTH = 20;
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+ import { passwordSchema, confirmPasswordSchema, strongPasswordSchema } from './utils/password.schema';
3
+ import {
4
+ MIN_FIRST_NAME_LENGTH,
5
+ MAX_FIRST_NAME_LENGTH,
6
+ MIN_LAST_NAME_LENGTH,
7
+ MAX_LAST_NAME_LENGTH,
8
+ MIN_ORGANIZATION_NAME_LENGTH,
9
+ MAX_ORGANIZATION_NAME_LENGTH
10
+ } from './auth.constants';
11
+
12
+ // =============================================================================
13
+ // AUTH SCHEMAS
14
+ // =============================================================================
15
+
16
+ // Login schema
17
+ export const loginSchema = z.object({
18
+ email: z.string().email('Please enter a valid email address'),
19
+ password: z.string().min(1, 'Password is required'),
20
+ });
21
+
22
+ // Base user schema
23
+ const baseUserSchema = z.object({
24
+ firstName: z.string()
25
+ .trim()
26
+ .min(MIN_FIRST_NAME_LENGTH, `First name must be at least ${MIN_FIRST_NAME_LENGTH} characters long`)
27
+ .max(MAX_FIRST_NAME_LENGTH, `First name must be at most ${MAX_FIRST_NAME_LENGTH} characters long`),
28
+ lastName: z.string()
29
+ .trim()
30
+ .min(MIN_LAST_NAME_LENGTH, `Last name must be at least ${MIN_LAST_NAME_LENGTH} characters long`)
31
+ .max(MAX_LAST_NAME_LENGTH, `Last name must be at most ${MAX_LAST_NAME_LENGTH} characters long`),
32
+ email: z.string().trim().email(),
33
+ password: strongPasswordSchema,
34
+ confirmPassword: confirmPasswordSchema,
35
+ });
36
+
37
+ // Register schema for regular users
38
+ export const registerSchema = baseUserSchema.extend({
39
+ organizationName: z.string().optional(),
40
+ organizationType: z.enum(['Venue', 'Promoter', 'Festival Organizer']).optional(),
41
+ }).refine((data) => data.password === data.confirmPassword, {
42
+ message: "Passwords don't match",
43
+ path: ["confirmPassword"],
44
+ });
45
+
46
+ // Register schema for host users
47
+ export const registerHostSchema = baseUserSchema.extend({
48
+ organizationName: z.string()
49
+ .trim()
50
+ .min(MIN_ORGANIZATION_NAME_LENGTH, `Organization name must be at least ${MIN_ORGANIZATION_NAME_LENGTH} characters long`)
51
+ .max(MAX_ORGANIZATION_NAME_LENGTH, `Organization name must be at most ${MAX_ORGANIZATION_NAME_LENGTH} characters long`),
52
+ }).refine((data) => data.password === data.confirmPassword, {
53
+ message: 'Passwords do not match',
54
+ path: ['confirmPassword'],
55
+ });
56
+
57
+
58
+ export const updateGoogleUserOrganizationSchema = z.object({
59
+ organization: z.string()
60
+ .trim()
61
+ .min(MIN_ORGANIZATION_NAME_LENGTH, `Organization name must be at least ${MIN_ORGANIZATION_NAME_LENGTH} characters long`)
62
+ .max(MAX_ORGANIZATION_NAME_LENGTH, `Organization name must be at most ${MAX_ORGANIZATION_NAME_LENGTH} characters long`),
63
+ id: z.string({ required_error: 'Unauthorized' }).regex(/^[0-9a-fA-F]{24}$/, 'Unauthorized'),
64
+ });
65
+
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ import { loginSchema, registerSchema, registerHostSchema, updateGoogleUserOrganizationSchema } from './auth.schema';
3
+
4
+ // =============================================================================
5
+ // TYPE EXPORTS
6
+ // =============================================================================
7
+
8
+ export type LoginData = z.infer<typeof loginSchema>;
9
+ export type RegisterData = z.infer<typeof registerSchema>;
10
+ export type RegisterHostData = z.infer<typeof registerHostSchema>;
11
+ export type UpdateGoogleUserOrganizationData = z.infer<typeof updateGoogleUserOrganizationSchema>;
12
+
13
+ // Payload interfaces for API
14
+ export interface LoginPayload {
15
+ email: string;
16
+ password: string;
17
+ }
18
+
19
+ export interface RegisterPayload {
20
+ firstName: string;
21
+ lastName: string;
22
+ email: string;
23
+ password: string;
24
+ confirmPassword: string;
25
+ organizationName?: string;
26
+ }
27
+
28
+ export interface RegisterHostPayload extends RegisterPayload {
29
+ organizationName: string;
30
+ }
31
+
32
+ export interface JwtTokenPayload {
33
+ sub: string;
34
+ email: string;
35
+ role: string;
36
+ firstName?: string;
37
+ lastName?: string;
38
+ organization?: string;
39
+ phone?: string;
40
+ }
41
+
42
+ export type Role = 'user' | 'host' | 'admin';
@@ -0,0 +1,3 @@
1
+ export * from './auth.schema';
2
+ export * from './auth.type';
3
+ export * from './auth.constants';
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ import zxcvbn from 'zxcvbn';
3
+
4
+ export const passwordSchema = z.string()
5
+ .min(8, 'Password must be at least 8 characters long')
6
+ .max(128, 'Password must be at most 128 characters long');
7
+
8
+ export const confirmPasswordSchema = z.string()
9
+ .min(8, 'Confirm password must be at least 8 characters long')
10
+ .max(128, 'Confirm password must be at most 128 characters long');
11
+
12
+ // Password strength validation
13
+ export const strongPasswordSchema = passwordSchema.refine(
14
+ (password) => zxcvbn(password).score >= 2,
15
+ {
16
+ message: 'Password must be strong (include uppercase, lowercase, numbers, and special characters)',
17
+ }
18
+ );
@@ -0,0 +1,170 @@
1
+ import { EventType, DraftEventData, AgeRestriction, VenueType, DisplayTicket } from "./events.type";
2
+
3
+ export const MAX_TAGLINE_LENGTH = 150;
4
+ export const MAX_CATEGORIES = 3;
5
+ export const MAX_DESCRIPTION_LENGTH = 2000;
6
+ export const MAX_DOCUMENTS = 5;
7
+ export const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
8
+ export const MAX_FILE_SIZE_MB = 10;
9
+ export const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
10
+ export const ALLOWED_FILE_TYPES = ['image/jpeg', 'image/png', 'application/pdf'];
11
+ export const ALLOWED_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.pdf'];
12
+
13
+ export const CATEGORIES_BY_TYPE: Record<string, string[]> = {
14
+ concert: ['Rock', 'Pop', 'Jazz', 'Electronic', 'Indie', 'Metal', 'Acoustic', 'Classical'],
15
+ festival: ['Music', 'Food & Drink', 'Arts', 'Film', 'Culture', 'Tech', 'Family'],
16
+ conference: ['Technology', 'Business', 'Design', 'Marketing', 'Leadership', 'Startup', 'AI'],
17
+ theater: ['Drama', 'Comedy', 'Musical', 'Dance', 'Improv', 'Classical', 'Opera'],
18
+ sports: ['Football', 'Basketball', 'Tennis', 'Yoga', 'Fitness', 'Running', 'eSports'],
19
+ other: ['Community', 'Networking', 'Workshop', 'Meetup', 'Charity', 'Social', 'Party']
20
+ } as const;
21
+
22
+ export const EVENT_TYPES: Array<{
23
+ type: EventType;
24
+ icon: string;
25
+ label: string;
26
+ }> = [
27
+ { type: 'concert', icon: 'Music', label: 'Concert' },
28
+ { type: 'festival', icon: 'Tent', label: 'Festival' },
29
+ { type: 'conference', icon: 'Mic2', label: 'Seminar' },
30
+ { type: 'theater', icon: 'Theater', label: 'Performance' },
31
+ { type: 'sports', icon: 'Trophy', label: 'Gala' },
32
+ { type: 'other', icon: 'MoreHorizontal', label: 'Other' }
33
+ ] as const;
34
+
35
+
36
+ export const SUPPORTED_LANGUAGES = [
37
+ 'English',
38
+ 'Bangla'
39
+ ] as const;
40
+
41
+ // Age restriction options with value (for form state) and label (for display)
42
+ export const AGE_RESTRICTIONS: Array<{
43
+ value: AgeRestriction;
44
+ label: string;
45
+ }> = [
46
+ { value: 'all_ages', label: 'All Ages' },
47
+ { value: '18+', label: '18+' },
48
+ { value: '21+', label: '21+' },
49
+ ] as const;
50
+
51
+
52
+
53
+ export const IMAGE_PLACEHOLDER_TEXT = {
54
+ dropzone: 'Drop your image here',
55
+ formats: 'Supports JPG, PNG, GIF (Max 5MB)',
56
+ change: 'Change Image'
57
+ } as const;
58
+
59
+
60
+
61
+
62
+ export const HOURS = Array.from({ length: 12 }, (_, i) => i + 1);
63
+ export const MINUTES = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'));
64
+ export const AMPM = ['AM', 'PM'] as const;
65
+ export const TIME_PRESETS = [
66
+ { label: '9 am', h: 9, m: '00', p: 'AM' },
67
+ { label: '12 pm', h: 12, m: '00', p: 'PM' },
68
+ { label: '4 pm', h: 4, m: '00', p: 'PM' },
69
+ { label: '6 pm', h: 6, m: '00', p: 'PM' }
70
+ ] as const;
71
+
72
+ export const VENUE_TYPES: Array<{
73
+ value: VenueType;
74
+ label: string;
75
+ icon: string;
76
+ }> = [
77
+ { value: 'indoor', label: 'Indoor', icon: 'Building' },
78
+ { value: 'outdoor', label: 'Outdoor', icon: 'Mountain' },
79
+ { value: 'hybrid', label: 'Hybrid', icon: 'Building2' }
80
+ ] as const;
81
+
82
+ export const STEPS = [
83
+ { id: 1, label: 'Basics', description: 'Event Basics' },
84
+ { id: 2, label: 'Details', description: 'Event Details' },
85
+ { id: 3, label: 'Logistics', description: 'Date & Venue' },
86
+ { id: 4, label: 'Verify', description: 'Verification' },
87
+ { id: 5, label: 'Tickets', description: 'Ticket Setup' },
88
+ { id: 6, label: 'Review', description: 'Review & Publish' },
89
+ ];
90
+
91
+ export const PREDEFINED_BENEFITS = [
92
+ 'Early entry',
93
+ 'Access to general area',
94
+ 'VIP seating',
95
+ 'Meet & greet',
96
+ 'Backstage access',
97
+ 'Complimentary drink',
98
+ 'Priority parking',
99
+ 'Exclusive merchandise'
100
+ ] as const;
101
+
102
+ // Helper function to get tomorrow's date in ISO format
103
+ const getTomorrowISOString = (): string => {
104
+ const tomorrow = new Date();
105
+ tomorrow.setDate(tomorrow.getDate() + 1);
106
+ tomorrow.setHours(18, 0, 0, 0); // Default to 6 PM tomorrow
107
+ return tomorrow.toISOString();
108
+ };
109
+
110
+ const getDayAfterTomorrowISOString = (): string => {
111
+ const dayAfterTomorrow = new Date();
112
+ dayAfterTomorrow.setDate(dayAfterTomorrow.getDate() + 2);
113
+ dayAfterTomorrow.setHours(18, 0, 0, 0); // Default to 6 PM day after tomorrow
114
+ return dayAfterTomorrow.toISOString();
115
+ };
116
+
117
+ export const INITIAL_DATA: DraftEventData = {
118
+ title: '',
119
+ tagline: '',
120
+ type: 'concert',
121
+ categories: [],
122
+ description: '',
123
+ media: {
124
+ coverImage: {
125
+ url: '',
126
+ thumbnailUrl: '',
127
+ alt: ''
128
+ },
129
+ gallery: []
130
+ },
131
+ language: 'English',
132
+ ageRestriction: 'all_ages',
133
+ dressCode: 'casual',
134
+ schedule: {
135
+ startDate: getTomorrowISOString(),
136
+ endDate: getDayAfterTomorrowISOString(),
137
+ },
138
+ venue: {
139
+ name: '',
140
+ type: 'indoor',
141
+ address: {
142
+ street: '',
143
+ city: '',
144
+ country: '',
145
+ },
146
+ coordinates: {
147
+ type: 'Point',
148
+ coordinates: [0, 0],
149
+ },
150
+ capacity: 100,
151
+ parking: false,
152
+ publicTransit: ''
153
+ },
154
+ organizer: {
155
+ role: 'event_organizer',
156
+ contactPerson: {
157
+ name: '',
158
+ email: '',
159
+ phone: '',
160
+ },
161
+ companyName: ''
162
+ },
163
+ verification: {
164
+ documents: [],
165
+ },
166
+ tickets: [],
167
+ termsAccepted: false,
168
+ legalPermissionAccepted: false,
169
+ platformTermsAccepted: false,
170
+ };
@@ -0,0 +1,158 @@
1
+ import { z } from 'zod';
2
+ import { eventTypeSchema } from './utils/event.type.schema';
3
+ import { mediaSchema } from './utils/media.schema';
4
+ import { scheduleSchema } from './utils/schedule.schema';
5
+ import { venueSchema } from './utils/venue.schema';
6
+ import { organizerSchema } from './utils/organizer.schema';
7
+ import { documentSchema } from './utils/document.schema';
8
+ import { displayTicketSchema } from './utils/ticket.schema';
9
+ import { MAX_TAGLINE_LENGTH, MAX_CATEGORIES, MAX_DESCRIPTION_LENGTH, MAX_DOCUMENTS } from './events.constants';
10
+ import { ageRestrictionSchema } from './utils/age.restriction.schema';
11
+
12
+
13
+ // =============================================================================
14
+ // STEP SCHEMAS
15
+ // =============================================================================
16
+
17
+ // Step 1: Basics
18
+ export const stepBasicsSchema = z.object({
19
+ title: z.string({ required_error: 'Event title is required' }).min(10, 'Event title must be at least 10 characters').max(100, 'Title must be less than 100 characters'),
20
+ tagline: z.string().min(5, 'Tagline must be at least 5 characters').max(MAX_TAGLINE_LENGTH, `Tagline cannot exceed ${MAX_TAGLINE_LENGTH} characters`).optional(),
21
+ type: eventTypeSchema,
22
+ categories: z.array(z.string()).max(MAX_CATEGORIES, `Maximum ${MAX_CATEGORIES} categories allowed`).optional(),
23
+ }).passthrough();
24
+
25
+ // Step 2: Details
26
+ export const stepDetailsSchema = z.object({
27
+ media: mediaSchema,
28
+ description: z.string({ required_error: 'Event description is required' }).min(50, 'Description must be at least 50 characters').max(MAX_DESCRIPTION_LENGTH, `Description cannot exceed ${MAX_DESCRIPTION_LENGTH} characters`),
29
+ highlights: z.array(z.string().max(100, 'Each highlight cannot exceed 100 characters'), { required_error: 'Highlights must be an array of strings' }).max(10, 'Cannot have more than 10 highlights').optional(),
30
+ language: z.string({ required_error: 'Language is required' }),
31
+ ageRestriction: ageRestrictionSchema,
32
+ dressCode: z.enum(['casual', 'formal', 'semi-formal', 'other'], {required_error: "Dress code is required"}).optional(),
33
+ }).passthrough();
34
+
35
+ // Step 3: Logistics
36
+ export const stepLogisticsSchema = z.object({
37
+ schedule: scheduleSchema,
38
+ venue: venueSchema
39
+ }).passthrough().refine((data) => {
40
+ if (data.schedule.startDate && data.schedule.endDate) {
41
+ return new Date(data.schedule.endDate) > new Date(data.schedule.startDate);
42
+ }
43
+ return true;
44
+ }, {
45
+ message: "End date and time must be after start date and time",
46
+ path: ["schedule", "endDate"]
47
+ });
48
+
49
+ // Step 4: Verification
50
+ export const stepVerifySchema = z.object({
51
+ organizer: organizerSchema,
52
+ verification: z.object({
53
+ documents: z.array(documentSchema).min(1, 'At least one document is required').max(MAX_DOCUMENTS, `Maximum ${MAX_DOCUMENTS} documents allowed`)
54
+ })
55
+ }).passthrough();
56
+
57
+ // Step 5: Tickets
58
+ export const stepTicketsSchema = z.object({
59
+ tickets: z.array(displayTicketSchema).min(1, 'At least one ticket type is required')
60
+ }).passthrough().refine((data) => {
61
+ return data.tickets.length >= 1;
62
+ }, {
63
+ message: "At least one ticket type is required",
64
+ path: ["tickets"]
65
+ }).refine(data=> {
66
+ for (const ticket of data.tickets) {
67
+ if (ticket.salesWindow?.startDate && ticket.salesWindow?.endDate) {
68
+ if (new Date(ticket.salesWindow.endDate) <= new Date(ticket.salesWindow.startDate)) {
69
+ return false;
70
+ }
71
+ }
72
+ }
73
+ return true;
74
+ }, {
75
+ message: "End date and time must be after start date and time",
76
+ path: ["tickets", "salesWindow", "endDate"]
77
+ });
78
+
79
+ // Step 6: Review
80
+ export const stepReviewSchema = z.object({
81
+ termsAccepted: z.boolean().refine(val => val === true, {
82
+ message: 'You must accept all terms and conditions to publish this event'
83
+ }),
84
+ legalPermissionAccepted: z.boolean().refine(val => val === true, {
85
+ message: 'Legal permission confirmation is required'
86
+ }),
87
+ platformTermsAccepted: z.boolean().refine(val => val === true, {
88
+ message: 'Platform terms acceptance is required'
89
+ })
90
+ }).passthrough();
91
+
92
+ export const getEventSchema = z.object({
93
+ eventId: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Event not found').optional(),
94
+ });
95
+
96
+ export const protectedEventSchema = z.object({
97
+ eventId: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Event not found'),
98
+ hostId: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Unauthorized'),
99
+ });
100
+
101
+ export const pendingApprovalEditSchema = z.object({
102
+ eventId: z.string({ required_error: 'Event not found' }).regex(/^[0-9a-fA-F]{24}$/, 'Event not found'),
103
+ hostId: z.string({ required_error: 'Unauthorized' }).regex(/^[0-9a-fA-F]{24}$/, 'Unauthorized'),
104
+ media: mediaSchema,
105
+ description: z.string({ required_error: 'Event description is required' }).min(50, 'Description must be at least 50 characters').max(MAX_DESCRIPTION_LENGTH, `Description cannot exceed ${MAX_DESCRIPTION_LENGTH} characters`),
106
+ })
107
+
108
+ export const approvedEventEditSchema = z.object({
109
+ eventId: z.string({ required_error: 'Event not found' }).regex(/^[0-9a-fA-F]{24}$/, 'Event not found'),
110
+ hostId: z.string({ required_error: 'Unauthorized' }).regex(/^[0-9a-fA-F]{24}$/, 'Unauthorized'),
111
+ media: mediaSchema,
112
+ description: z.string({ required_error: 'Event description is required' }).min(50, 'Description must be at least 50 characters').max(MAX_DESCRIPTION_LENGTH, `Description cannot exceed ${MAX_DESCRIPTION_LENGTH} characters`),
113
+ tickets: z.array(displayTicketSchema).min(1, 'At least one ticket type is required'),
114
+ }).refine(data=> {
115
+ for (const ticket of data.tickets) {
116
+ if (ticket.salesWindow?.startDate && ticket.salesWindow?.endDate) {
117
+ if (new Date(ticket.salesWindow.endDate) <= new Date(ticket.salesWindow.startDate)) {
118
+ return false;
119
+ }
120
+ }
121
+ }
122
+ return true;
123
+ }, {
124
+ message: "End date and time must be after start date and time",
125
+ path: ["tickets", "salesWindow", "endDate"]
126
+ })
127
+
128
+ // =============================================================================
129
+ // COMPOSITE SCHEMAS
130
+ // =============================================================================
131
+
132
+ export const submitEventSchema = stepBasicsSchema
133
+ .merge(stepDetailsSchema)
134
+ .merge(stepLogisticsSchema._def.schema)
135
+ .merge(stepVerifySchema)
136
+ .merge(stepTicketsSchema._def.schema._def.schema)
137
+ .merge(stepReviewSchema)
138
+ .extend({
139
+ eventId: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Event not found').optional(),
140
+ hostId: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Unauthorized').optional(),
141
+ });
142
+
143
+ export const clientGetEventSchema = stepBasicsSchema
144
+ .merge(stepDetailsSchema)
145
+ .merge(stepLogisticsSchema._def.schema)
146
+ .merge(stepVerifySchema)
147
+ .merge(stepTicketsSchema._def.schema._def.schema)
148
+ .merge(stepReviewSchema)
149
+ .extend({
150
+ _id: z.string().regex(/^[0-9a-fA-F]{24}$/, 'Event not found'),
151
+ status: z.enum(['draft', 'pending_approval', 'approved', 'rejected', 'published', 'live', 'ended', 'cancelled'], { required_error: 'Event status is required' }).default('draft'),
152
+ });
153
+
154
+ export const draftEventSchema = submitEventSchema
155
+ .partial()
156
+ .extend({
157
+ title: stepBasicsSchema.shape.title,
158
+ });
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ import { mediaSchema } from './utils/media.schema';
3
+ import { scheduleSchema } from './utils/schedule.schema';
4
+ import { venueSchema } from './utils/venue.schema';
5
+ import { organizerSchema } from './utils/organizer.schema';
6
+ import { documentSchema } from './utils/document.schema';
7
+ import { displayTicketSchema } from './utils/ticket.schema';
8
+ import { eventTypeSchema } from './utils/event.type.schema';
9
+ import { ageRestrictionSchema } from './utils/age.restriction.schema';
10
+ import { stepBasicsSchema, getEventSchema, protectedEventSchema, clientGetEventSchema, stepDetailsSchema, stepLogisticsSchema, stepVerifySchema, stepTicketsSchema, stepReviewSchema, submitEventSchema, draftEventSchema, pendingApprovalEditSchema, approvedEventEditSchema } from './events.schema';
11
+
12
+ // =============================================================================
13
+ // TYPE EXPORTS
14
+ // =============================================================================
15
+
16
+ // Document type is now imported from media module
17
+ export type Media = z.infer<typeof mediaSchema>;
18
+ export type CoverImage = z.infer<typeof mediaSchema.shape.coverImage>;
19
+ export type Gallery = z.infer<typeof mediaSchema.shape.gallery>;
20
+ export type Organizer = z.infer<typeof organizerSchema>;
21
+ export type ContactPerson = z.infer<typeof organizerSchema.shape.contactPerson>;
22
+ export type Schedule = z.infer<typeof scheduleSchema>;
23
+ export type DisplayTicket = z.infer<typeof displayTicketSchema>;
24
+ export type Price = z.infer<typeof displayTicketSchema.shape.price>;
25
+ export type SalesWindow = z.infer<typeof displayTicketSchema.shape.salesWindow>;
26
+ export type Limits = z.infer<typeof displayTicketSchema.shape.limits>;
27
+ export type Venue = z.infer<typeof venueSchema>;
28
+ export type VenueType = z.infer<typeof venueSchema.shape.type>;
29
+ export type Address = z.infer<typeof venueSchema.shape.address>;
30
+ export type Document = z.infer<typeof documentSchema>;
31
+
32
+ // Shared enum types
33
+ export type EventType = z.infer<typeof eventTypeSchema>;
34
+ export type AgeRestriction = z.infer<typeof ageRestrictionSchema>;
35
+
36
+ // Step data types
37
+ export type StepBasicsData = z.infer<typeof stepBasicsSchema>;
38
+ export type StepDetailsData = z.infer<typeof stepDetailsSchema>;
39
+ export type StepLogisticsData = z.infer<typeof stepLogisticsSchema>;
40
+ export type StepVerifyData = z.infer<typeof stepVerifySchema>;
41
+ export type StepTicketsData = z.infer<typeof stepTicketsSchema>;
42
+ export type StepReviewData = z.infer<typeof stepReviewSchema>;
43
+
44
+ // Composite types
45
+ export type SubmitEventData = z.infer<typeof submitEventSchema>;
46
+ export type DraftEventData = z.infer<typeof draftEventSchema>;
47
+ export type GetEventData = z.infer<typeof getEventSchema>;
48
+ export type ProtectedEventData = z.infer<typeof protectedEventSchema>;
49
+ export type ClientGetEventData = z.infer<typeof clientGetEventSchema>;
50
+ export type PendingApprovalEditData = z.infer<typeof pendingApprovalEditSchema>;
51
+ export type ApprovedEventEditData = z.infer<typeof approvedEventEditSchema>;
@@ -0,0 +1,5 @@
1
+ export * from './utils/admin.schema';
2
+ export * from './utils/media.schema';
3
+ export * from './utils/ticket.schema';
4
+ export * from './utils/organizer.schema';
5
+ export * from './utils/venue.schema';
@@ -1,3 +1,4 @@
1
- export * from './events.schema';
2
- export * from './events.type';
3
- export * from './events.utils.schema';
1
+ export * from './events.schema';
2
+ export * from './events.type';
3
+ export * from './events.utils.schema';
4
+ export * from './events.constants';