@zyacreatives/shared 2.5.49 → 2.5.51

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.
@@ -13,333 +13,209 @@ import {
13
13
  import { CuidSchema, ProfileIdentifierSchema } from "./common";
14
14
  import { MinimalUserSchema } from "./user";
15
15
 
16
- const WebsiteUrlInputSchema = z
17
- .string()
18
- .transform((val) => {
19
- if (!val) return val;
20
- if (val.startsWith("http://") || val.startsWith("https://")) {
21
- return val;
22
- }
23
- return `https://${val}`;
24
- })
25
- .pipe(z.url("Invalid URL").or(z.literal("")))
26
- .optional();
16
+ /**
17
+ * --------------------------------
18
+ * SHAPE
19
+ * --------------------------------
20
+ */
27
21
 
28
- const InvestorLinkSchema = z.object({
29
- url: z.union([z.url({ message: "Please enter a valid URL" }), z.literal("")]),
30
- type: z.enum(LINK_TYPES),
31
- });
22
+ const InvestorShape = z.object({
23
+ bio: z.string().max(600).default(""),
24
+ location: z.string().default(""),
32
25
 
33
- const InvestorAchievementSchema = z.object({
34
- title: z.string(),
35
- link: z.string().optional(),
36
- year: z.coerce.number().int().optional(),
37
- });
26
+ experienceLevel: z.enum(
27
+ Object.values(EXPERIENCE_LEVELS) as [ExperienceLevel, ...ExperienceLevel[]],
28
+ ),
38
29
 
39
- export const MinimalInvestorEntitySchema = z.object({
40
- id: z.cuid2().openapi({ example: "inv_cksd0v6q0000s9a5y8z7p3x9" }),
41
- userId: z.cuid2().openapi({ example: "user_owner_123" }),
42
- bio: z
43
- .string()
44
- .optional()
45
- .openapi({ example: "Early stage VC focusing on creative technology." }),
46
- location: z.string().optional().openapi({ example: "New York, USA" }),
47
- experienceLevel: z
48
- .enum(
49
- Object.values(EXPERIENCE_LEVELS) as [
50
- ExperienceLevel,
51
- ...ExperienceLevel[],
52
- ],
53
- )
54
- .optional()
55
- .openapi({ example: "EXPERT" }),
56
- investorType: z
57
- .enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
58
- .optional()
59
- .openapi({ example: "VC" }),
60
- investmentSize: z
61
- .enum(
62
- Object.values(INVESTMENT_SIZES) as [InvestmentSize, ...InvestmentSize[]],
30
+ investorType: z.enum(
31
+ Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]],
32
+ ),
33
+
34
+ investmentSize: z.enum(
35
+ Object.values(INVESTMENT_SIZES) as [InvestmentSize, ...InvestmentSize[]],
36
+ ),
37
+
38
+ geographicFocus: z.enum(
39
+ Object.values(GEOGRAPHIC_FOCUS) as [GeographicFocus, ...GeographicFocus[]],
40
+ ),
41
+
42
+ websiteURL: z.url().default(""),
43
+
44
+ disciplines: z.array(z.string()).default([]),
45
+
46
+ links: z
47
+ .array(
48
+ z.object({
49
+ url: z.url(),
50
+ type: z.enum(LINK_TYPES).default(LINK_TYPES.GENERIC_WEBSITE),
51
+ }),
63
52
  )
64
- .optional()
65
- .openapi({
66
- example: "SEED",
67
- }),
68
- geographicFocus: z
69
- .enum(
70
- Object.values(GEOGRAPHIC_FOCUS) as [
71
- GeographicFocus,
72
- ...GeographicFocus[],
73
- ],
53
+ .default([]),
54
+
55
+ achievements: z
56
+ .array(
57
+ z.object({
58
+ title: z.string(),
59
+ link: z.url().optional(),
60
+ year: z.number().int().optional(),
61
+ }),
74
62
  )
75
- .optional()
76
- .openapi({
77
- example: "GLOBAL",
78
- }),
79
- websiteURL: z
80
- .url()
81
- .optional()
82
- .openapi({ example: "https://investorpartners.com" }),
83
- disciplines: z
84
- .array(z.string())
85
- .optional()
86
- .openapi({ example: ["Product Design", "AI Strategy"] }),
87
- createdAt: z.coerce
88
- .date()
89
- .optional()
90
- .openapi({ example: "2025-10-13T09:00:00.000Z" }),
91
- updatedAt: z.coerce
92
- .date()
93
- .optional()
94
- .openapi({ example: "2025-10-13T09:00:00.000Z" }),
63
+ .default([]),
95
64
  });
96
65
 
97
- export type MinimalInvestorEntity = z.infer<typeof MinimalInvestorEntitySchema>;
66
+ export type InvestorShapeType = z.infer<typeof InvestorShape>;
67
+
68
+ /**
69
+ * --------------------------------
70
+ * ENTITY (DTO)
71
+ * --------------------------------
72
+ */
98
73
 
99
74
  export const InvestorEntitySchema = z
100
75
  .object({
101
- id: z.cuid2().openapi({ example: "inv_cksd0v6q0000s9a5y8z7p3x9" }),
102
- userId: z.cuid2().openapi({ example: "user_owner_123" }),
103
- bio: z
104
- .string()
105
- .optional()
106
- .openapi({ example: "Early stage VC focusing on creative technology." }),
107
- location: z.string().optional().openapi({ example: "New York, USA" }),
108
- experienceLevel: z
109
- .enum(
110
- Object.values(EXPERIENCE_LEVELS) as [
111
- ExperienceLevel,
112
- ...ExperienceLevel[],
113
- ],
114
- )
115
- .optional()
116
- .openapi({ example: "EXPERT" }),
117
- geographicFocus: z
118
- .enum(
119
- Object.values(GEOGRAPHIC_FOCUS) as [
120
- GeographicFocus,
121
- ...GeographicFocus[],
122
- ],
123
- )
124
- .optional()
125
- .openapi({ example: "NORTH_AMERICA" }),
126
- investmentSize: z
127
- .enum(
128
- Object.values(INVESTMENT_SIZES) as [
129
- InvestmentSize,
130
- ...InvestmentSize[],
131
- ],
132
- )
133
- .optional()
134
- .openapi({ example: "SEED" }),
135
- investorType: z
136
- .enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
137
- .optional()
138
- .openapi({ example: "VC" }),
139
- websiteURL: z
140
- .url()
141
- .optional()
142
- .openapi({ example: "https://investorpartners.com" }),
143
- links: z.array(InvestorLinkSchema).optional(),
144
- achievements: z.array(InvestorAchievementSchema).optional(),
145
- disciplines: z
146
- .array(z.string())
147
- .optional()
148
- .openapi({ example: ["Product Design", "AI Strategy"] }),
149
- createdAt: z.coerce
150
- .date()
151
- .optional()
152
- .openapi({ example: "2025-10-13T09:00:00.000Z" }),
153
- updatedAt: z.coerce
154
- .date()
155
- .optional()
156
- .openapi({ example: "2025-10-13T09:00:00.000Z" }),
76
+ id: z.cuid2(),
77
+ userId: z.cuid2(),
78
+ ...InvestorShape.shape,
79
+ createdAt: z.iso.datetime(),
80
+ updatedAt: z.iso.datetime(),
157
81
  version: z.int(),
158
82
  })
159
- .openapi("InvestorEntity");
83
+ .openapi("Investor");
160
84
 
161
85
  export type InvestorEntity = z.infer<typeof InvestorEntitySchema>;
162
86
 
163
- export const InvestorWithUserEntitySchema = MinimalInvestorEntitySchema.extend({
164
- user: MinimalUserSchema,
87
+ /**
88
+ * Minimal version = derived, not duplicated
89
+ */
90
+
91
+ export const MinimalInvestorEntitySchema = InvestorEntitySchema.pick({
92
+ id: true,
93
+ userId: true,
94
+ bio: true,
95
+ location: true,
96
+ experienceLevel: true,
97
+ investorType: true,
98
+ investmentSize: true,
99
+ geographicFocus: true,
100
+ websiteURL: true,
101
+ disciplines: true,
102
+ createdAt: true,
103
+ updatedAt: true,
165
104
  });
166
105
 
167
- export type InvestorWithUserEntity = z.infer<
168
- typeof InvestorWithUserEntitySchema
169
- >;
106
+ export type MinimalInvestorEntity = z.infer<typeof MinimalInvestorEntitySchema>;
170
107
 
171
- export const CreateInvestorProfileInputSchema = z
172
- .object({
173
- websiteURL: WebsiteUrlInputSchema,
174
- experienceLevel: z
175
- .enum(
176
- Object.values(EXPERIENCE_LEVELS) as [
177
- ExperienceLevel,
178
- ...ExperienceLevel[],
179
- ],
180
- )
181
- .openapi({
182
- example: "0-1 year",
183
- }),
184
- location: z.string().openapi({
185
- example: "UK",
186
- }),
187
- })
188
- .openapi({
189
- title: "Create Investor Profile",
190
- });
108
+ /**
109
+ * --------------------------------
110
+ * INPUT DTOs
111
+ * --------------------------------
112
+ */
113
+
114
+ export const CreateInvestorProfileInputSchema = InvestorShape.pick({
115
+ experienceLevel: true,
116
+ location: true,
117
+ websiteURL: true,
118
+ }).extend({
119
+ disciplineSlugs: z.array(z.string()).min(1),
120
+ });
191
121
 
192
122
  export type CreateInvestorInput = z.infer<
193
123
  typeof CreateInvestorProfileInputSchema
194
124
  >;
195
125
 
196
- export const UpdateInvestorProfileInputSchema = z
197
- .object({
198
- bio: z.string().max(600).optional().openapi({
199
- example: "Seasoned venture capitalist with a focus on healthtech.",
200
- }),
201
- websiteURL: WebsiteUrlInputSchema,
202
- experienceLevel: z
203
- .enum(
204
- Object.values(EXPERIENCE_LEVELS) as [
205
- ExperienceLevel,
206
- ...ExperienceLevel[],
207
- ],
208
- )
209
- .optional()
210
- .openapi({
211
- example: "SENIOR",
212
- }),
213
- investorType: z
214
- .enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
215
- .optional()
216
- .openapi({
217
- example: "VC",
218
- }),
219
- disciplineSlugs: z
220
- .array(z.string())
221
- .min(1, "At least one discipline is required")
222
- .optional()
223
- .openapi({
224
- example: ["fintech", "edtech"],
225
- }),
226
- investmentSize: z
227
- .enum(
228
- Object.values(INVESTMENT_SIZES) as [
229
- InvestmentSize,
230
- ...InvestmentSize[],
231
- ],
232
- )
233
- .optional()
234
- .openapi({
235
- example: "SEED",
236
- }),
237
- geographicFocus: z
238
- .enum(
239
- Object.values(GEOGRAPHIC_FOCUS) as [
240
- GeographicFocus,
241
- ...GeographicFocus[],
242
- ],
243
- )
244
- .optional()
245
- .openapi({
246
- example: "GLOBAL",
247
- }),
248
- links: z.array(InvestorLinkSchema).optional(),
249
- achievements: z.array(InvestorAchievementSchema).optional(),
250
- location: z.string().optional().openapi({
251
- example: "UK",
252
- }),
126
+ export const UpdateInvestorProfileInputSchema = InvestorShape.partial()
127
+ .extend({
128
+ disciplineSlugs: z.array(z.string()).optional(),
253
129
  version: z.int(),
254
130
  })
255
- .openapi({
256
- title: "Update Investor Profile",
131
+ .refine((d) => Object.values(d).some((v) => v !== undefined), {
132
+ message: "At least one field must be provided",
257
133
  });
258
134
 
259
135
  export type UpdateInvestorInput = z.infer<
260
136
  typeof UpdateInvestorProfileInputSchema
261
137
  >;
262
138
 
263
- export const ListInvestorsInputSchema = z
264
- .object({
265
- query: z.string().optional().openapi({ example: "creative tech investor" }),
266
- disciplines: z
267
- .array(z.string())
268
- .optional()
269
- .openapi({ example: ["branding", "UX"] }),
270
- experienceLevels: z
271
- .array(
272
- z.enum(
273
- Object.values(EXPERIENCE_LEVELS) as [
274
- ExperienceLevel,
275
- ...ExperienceLevel[],
276
- ],
277
- ),
278
- )
279
- .optional()
280
- .openapi({
281
- description: "Filter based on the required experience level.",
282
- }),
283
- location: z.string().optional().openapi({ example: "San Francisco" }),
284
- tags: z
285
- .array(z.string())
286
- .optional()
287
- .openapi({ example: ["design", "future"] }),
288
- page: z.number().int().min(1).default(1).optional().openapi({ example: 1 }),
289
- perPage: z
290
- .number()
291
- .int()
292
- .min(1)
293
- .max(100)
294
- .default(20)
295
- .optional()
296
- .openapi({ example: 20 }),
297
- })
298
- .openapi("ListInvestorsInput");
299
-
300
- export type ListInvestorsInput = z.infer<typeof ListInvestorsInputSchema>;
301
-
302
- export const SearchInvestorInputSchema = z.object({
303
- string: z
304
- .string()
305
- .min(1, { message: "Search string cannot be empty" })
306
- .max(200, { message: "Search string cannot exceed 200 characters" }),
307
- limit: z.coerce
308
- .number()
309
- .int({ message: "Limit must be an integer" })
310
- .min(1, { message: "Limit must be at least 1" })
311
- .max(100, { message: "Limit cannot exceed 100" })
312
- .default(20),
313
- cursor: z.string().optional(),
314
- });
315
-
316
- export type SearchInvestorInput = z.infer<typeof SearchInvestorInputSchema>;
139
+ /**
140
+ * --------------------------------
141
+ * GET / SEARCH
142
+ * --------------------------------
143
+ */
317
144
 
318
145
  export const GetInvestorParamsSchema = z.object({
319
146
  value: CuidSchema,
320
147
  });
321
148
 
322
- export type GetInvestorParams = z.infer<typeof GetInvestorParamsSchema>;
323
-
324
149
  export const GetInvestorQuerySchema = ProfileIdentifierSchema;
325
150
 
326
- export type GetInvestorQuery = z.infer<typeof GetInvestorQuerySchema>;
151
+ /**
152
+ * --------------------------------
153
+ * OUTPUT
154
+ * --------------------------------
155
+ */
327
156
 
328
157
  export const CreateInvestorOutputSchema = InvestorEntitySchema;
158
+ export const GetInvestorOutputSchema = InvestorEntitySchema;
159
+ export const UpdateInvestorOutputSchema = InvestorEntitySchema;
329
160
 
330
161
  export type CreateInvestorOutput = z.infer<typeof CreateInvestorOutputSchema>;
162
+ export type GetInvestorOutput = z.infer<typeof GetInvestorOutputSchema>;
163
+ export type UpdateInvestorOutput = z.infer<typeof UpdateInvestorOutputSchema>;
331
164
 
332
- export const GetInvestorOutputSchema = InvestorEntitySchema;
165
+ /**
166
+ * --------------------------------
167
+ * ENTITY WITH USER
168
+ * --------------------------------
169
+ */
333
170
 
334
- export type GetInvestorOutput = z.infer<typeof GetInvestorOutputSchema>;
171
+ export const InvestorWithUserEntitySchema = MinimalInvestorEntitySchema.extend({
172
+ user: MinimalUserSchema,
173
+ });
335
174
 
336
- export const UpdateInvestorOutputSchema = InvestorEntitySchema;
175
+ export type InvestorWithUserEntity = z.infer<
176
+ typeof InvestorWithUserEntitySchema
177
+ >;
337
178
 
338
- export type UpdateInvestorOutput = z.infer<typeof UpdateInvestorOutputSchema>;
179
+ /**
180
+ * --------------------------------
181
+ * LIST / SEARCH
182
+ * --------------------------------
183
+ */
184
+
185
+ export const ListInvestorsInputSchema = z.object({
186
+ query: z.string().default(""),
187
+ disciplines: z.array(z.string()).optional(),
188
+ experienceLevels: z
189
+ .array(
190
+ z.enum(
191
+ Object.values(EXPERIENCE_LEVELS) as [
192
+ ExperienceLevel,
193
+ ...ExperienceLevel[],
194
+ ],
195
+ ),
196
+ )
197
+ .optional(),
198
+
199
+ location: z.string().optional(),
200
+ tags: z.array(z.string()).optional(),
201
+
202
+ page: z.coerce.number().int().min(1).default(1),
203
+ perPage: z.coerce.number().int().min(1).max(100).default(20),
204
+ });
205
+
206
+ export type ListInvestorsInput = z.infer<typeof ListInvestorsInputSchema>;
207
+
208
+ export const SearchInvestorInputSchema = z.object({
209
+ string: z.string().min(1).max(200),
210
+ limit: z.coerce.number().int().min(1).max(100).default(20),
211
+ cursor: z.string().optional(),
212
+ });
213
+
214
+ export type SearchInvestorInput = z.infer<typeof SearchInvestorInputSchema>;
339
215
 
340
216
  export const SearchInvestorOutputSchema = z.object({
341
217
  investors: z.array(InvestorWithUserEntitySchema),
342
- nextCursor: z.string().optional().nullable(),
218
+ nextCursor: z.string().nullable().optional(),
343
219
  });
344
220
 
345
221
  export type SearchInvestorOutput = z.infer<typeof SearchInvestorOutputSchema>;