@zyacreatives/shared 1.1.3 → 1.2.1
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/schemas/brand.d.ts +46 -28
- package/dist/schemas/brand.js +48 -16
- package/dist/schemas/creative.d.ts +81 -21
- package/dist/schemas/creative.js +44 -14
- package/dist/schemas/investor.d.ts +351 -0
- package/dist/schemas/investor.js +162 -0
- package/dist/schemas/project.d.ts +116 -0
- package/dist/schemas/project.js +151 -0
- package/dist/schemas/user.d.ts +110 -46
- package/dist/schemas/user.js +46 -45
- package/dist/schemas/username.d.ts +1 -0
- package/dist/schemas/username.js +2 -0
- package/dist/types/brand.d.ts +13 -21
- package/dist/types/creative.d.ts +13 -25
- package/dist/types/investor.d.ts +13 -27
- package/dist/types/project.d.ts +5 -2
- package/dist/types/user.d.ts +10 -43
- package/dist/utils/slugify.d.ts +3 -0
- package/dist/utils/slugify.js +14 -0
- package/package.json +1 -1
- package/src/schemas/brand.ts +57 -34
- package/src/schemas/creative.ts +62 -35
- package/src/schemas/investor.ts +212 -0
- package/src/schemas/project.ts +161 -0
- package/src/schemas/user.ts +53 -71
- package/src/schemas/username.ts +0 -0
- package/src/types/brand.ts +35 -21
- package/src/types/creative.ts +38 -26
- package/src/types/investor.ts +38 -33
- package/src/types/project.ts +6 -2
- package/src/types/user.ts +33 -59
- package/src/utils/slugify.ts +10 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.slugify = void 0;
|
|
4
|
+
const slugify = ({ value }) => {
|
|
5
|
+
return value
|
|
6
|
+
.normalize("NFKD")
|
|
7
|
+
.replace(/[\u0300-\u036f]/g, "") // Remove diacritics
|
|
8
|
+
.toLowerCase()
|
|
9
|
+
.trim()
|
|
10
|
+
.replace(/[^a-z0-9]+/g, "_") // Replace non-alphanum with underscore
|
|
11
|
+
.replace(/^_+|_+$/g, "") // Trim leading/trailing underscores
|
|
12
|
+
.replace(/__+/g, "_"); // Collapse multiple underscores
|
|
13
|
+
};
|
|
14
|
+
exports.slugify = slugify;
|
package/package.json
CHANGED
package/src/schemas/brand.ts
CHANGED
|
@@ -1,35 +1,77 @@
|
|
|
1
1
|
import { z } from "@hono/zod-openapi";
|
|
2
2
|
import { CuidSchema, ProfileIdentifierSchema } from "./common";
|
|
3
3
|
import { MinimalUserSchema } from "./user";
|
|
4
|
+
import { EXPERIENCE_LEVELS, ExperienceLevel } from "../constants";
|
|
4
5
|
|
|
5
6
|
export const BrandEntitySchema = z
|
|
6
7
|
.object({
|
|
7
|
-
id: z.cuid2().openapi({ example: "
|
|
8
|
-
userId: z.cuid2().openapi({ example: "
|
|
9
|
-
brandName: z.string().
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
example: "A creative studio specializing in product design.",
|
|
13
|
-
}),
|
|
14
|
-
disciplines: z
|
|
15
|
-
.array(z.string())
|
|
8
|
+
id: z.cuid2().openapi({ example: "brd_cksd0v6q0000s9a5y8z7p3x9" }),
|
|
9
|
+
userId: z.cuid2().openapi({ example: "user_owner_123" }),
|
|
10
|
+
brandName: z.string().openapi({ example: "TechInnovate Inc." }),
|
|
11
|
+
bio: z
|
|
12
|
+
.string()
|
|
16
13
|
.optional()
|
|
17
|
-
.openapi({
|
|
18
|
-
example: ["graphic-design", "branding"],
|
|
19
|
-
}),
|
|
14
|
+
.openapi({ example: "Leading software development firm focused on AI." }),
|
|
20
15
|
tags: z
|
|
21
16
|
.array(z.string())
|
|
22
17
|
.optional()
|
|
23
|
-
.openapi({ example: ["
|
|
24
|
-
createdAt: z
|
|
18
|
+
.openapi({ example: ["technology", "saas", "startup"] }),
|
|
19
|
+
createdAt: z
|
|
20
|
+
.string()
|
|
25
21
|
.datetime()
|
|
26
22
|
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
27
|
-
updatedAt: z
|
|
23
|
+
updatedAt: z
|
|
24
|
+
.string()
|
|
28
25
|
.datetime()
|
|
29
26
|
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
30
27
|
})
|
|
31
28
|
.openapi("BrandEntity");
|
|
32
29
|
|
|
30
|
+
export const BrandWithUserEntitySchema = BrandEntitySchema.extend({
|
|
31
|
+
user: MinimalUserSchema,
|
|
32
|
+
disciplines: z
|
|
33
|
+
.array(z.string())
|
|
34
|
+
.openapi({ example: ["Marketing", "Product Development"] }),
|
|
35
|
+
}).openapi("BrandWithUserEntity");
|
|
36
|
+
|
|
37
|
+
export const ListBrandsInputSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
query: z.string().optional().openapi({ example: "AI software brand" }),
|
|
40
|
+
disciplines: z
|
|
41
|
+
.array(z.string())
|
|
42
|
+
.optional()
|
|
43
|
+
.openapi({ example: ["design", "marketing"] }),
|
|
44
|
+
experienceLevels: z
|
|
45
|
+
.array(
|
|
46
|
+
z.enum(
|
|
47
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
48
|
+
ExperienceLevel,
|
|
49
|
+
...ExperienceLevel[]
|
|
50
|
+
]
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
.optional()
|
|
54
|
+
.openapi({
|
|
55
|
+
description:
|
|
56
|
+
"Filter based on the required experience level of partners.",
|
|
57
|
+
}),
|
|
58
|
+
location: z.string().optional().openapi({ example: "San Francisco" }),
|
|
59
|
+
tags: z
|
|
60
|
+
.array(z.string())
|
|
61
|
+
.optional()
|
|
62
|
+
.openapi({ example: ["fintech", "remote"] }),
|
|
63
|
+
page: z.number().int().min(1).default(1).optional().openapi({ example: 1 }),
|
|
64
|
+
perPage: z
|
|
65
|
+
.number()
|
|
66
|
+
.int()
|
|
67
|
+
.min(1)
|
|
68
|
+
.max(100)
|
|
69
|
+
.default(20)
|
|
70
|
+
.optional()
|
|
71
|
+
.openapi({ example: 20 }),
|
|
72
|
+
})
|
|
73
|
+
.openapi("ListBrandsInput");
|
|
74
|
+
|
|
33
75
|
export const CreateBrandProfileSchema = z
|
|
34
76
|
.object({
|
|
35
77
|
brandName: z
|
|
@@ -76,22 +118,3 @@ export const GetBrandEndpointResponseSchema = BrandEntitySchema.extend({
|
|
|
76
118
|
});
|
|
77
119
|
export const UpdateBrandEndpointResponseSchema = BrandEntitySchema;
|
|
78
120
|
|
|
79
|
-
export type CreateBrandDto = z.infer<typeof CreateBrandProfileSchema> & {
|
|
80
|
-
userId: string;
|
|
81
|
-
};
|
|
82
|
-
export type UpdateBrandDto = z.infer<typeof UpdateBrandProfileSchema> & {
|
|
83
|
-
userId: string;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export type GetBrandParams = z.infer<typeof GetBrandParamsSchema>;
|
|
87
|
-
export type GetBrandQuery = z.infer<typeof GetBrandQuerySchema>;
|
|
88
|
-
|
|
89
|
-
export type CreateBrandEndpointResponse = z.infer<
|
|
90
|
-
typeof CreateBrandEndpointResponseSchema
|
|
91
|
-
>;
|
|
92
|
-
export type GetBrandEndpointResponse = z.infer<
|
|
93
|
-
typeof GetBrandEndpointResponseSchema
|
|
94
|
-
>;
|
|
95
|
-
export type UpdateBrandEndpointResponse = z.infer<
|
|
96
|
-
typeof UpdateBrandEndpointResponseSchema
|
|
97
|
-
>;
|
package/src/schemas/creative.ts
CHANGED
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import { z } from "@hono/zod-openapi";
|
|
2
|
-
import { EXPERIENCE_LEVELS } from "../constants";
|
|
2
|
+
import { EXPERIENCE_LEVELS, ExperienceLevel } from "../constants";
|
|
3
3
|
import { CuidSchema, ProfileIdentifierSchema } from "./common";
|
|
4
4
|
import { MinimalUserSchema } from "./user";
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const BaseCreativeEntitySchema = z
|
|
7
7
|
.object({
|
|
8
|
-
id: z.cuid2().openapi({ example: "
|
|
9
|
-
userId: z.cuid2().openapi({ example: "
|
|
10
|
-
bio: z
|
|
11
|
-
.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
location: z.string().optional().openapi({ example: "Lagos, Nigeria" }),
|
|
15
|
-
searchVector: z.string().optional(),
|
|
8
|
+
id: z.cuid2().openapi({ example: "cre_cksd0v6q0000s9a5y8z7p3x9" }),
|
|
9
|
+
userId: z.cuid2().openapi({ example: "user_abc123" }),
|
|
10
|
+
bio: z.string().optional().openapi({
|
|
11
|
+
example: "A multi-disciplinary designer specializing in brand identity.",
|
|
12
|
+
}),
|
|
13
|
+
location: z.string().optional().openapi({ example: "London, UK" }),
|
|
16
14
|
experienceLevel: z
|
|
17
|
-
.enum(
|
|
15
|
+
.enum(
|
|
16
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
17
|
+
ExperienceLevel,
|
|
18
|
+
...ExperienceLevel[]
|
|
19
|
+
]
|
|
20
|
+
)
|
|
18
21
|
.optional()
|
|
19
|
-
.openapi({ example: "
|
|
22
|
+
.openapi({ example: "SENIOR" }),
|
|
20
23
|
tags: z
|
|
21
24
|
.array(z.string())
|
|
22
25
|
.optional()
|
|
23
|
-
.openapi({ example: ["
|
|
26
|
+
.openapi({ example: ["branding", "typography", "UX"] }),
|
|
24
27
|
disciplines: z
|
|
25
28
|
.array(z.string())
|
|
26
29
|
.optional()
|
|
27
|
-
.openapi({ example: ["
|
|
30
|
+
.openapi({ example: ["Design", "Art Direction"] }),
|
|
31
|
+
user: z.any().optional(),
|
|
28
32
|
createdAt: z.iso
|
|
29
33
|
.datetime()
|
|
30
34
|
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
@@ -32,7 +36,49 @@ export const CreativeEntitySchema = z
|
|
|
32
36
|
.datetime()
|
|
33
37
|
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
34
38
|
})
|
|
35
|
-
.openapi("
|
|
39
|
+
.openapi("BaseCreativeEntity");
|
|
40
|
+
|
|
41
|
+
export const CreativeEntitySchema =
|
|
42
|
+
BaseCreativeEntitySchema.openapi("CreativeEntity");
|
|
43
|
+
|
|
44
|
+
export const CreativeWithUserEntitySchema = CreativeEntitySchema.extend({
|
|
45
|
+
user: MinimalUserSchema,
|
|
46
|
+
}).openapi("CreativeWithUserEntity");
|
|
47
|
+
|
|
48
|
+
export const ListCreativesInputSchema = z
|
|
49
|
+
.object({
|
|
50
|
+
query: z.string().optional().openapi({ example: "logo designer" }),
|
|
51
|
+
disciplines: z
|
|
52
|
+
.array(z.string())
|
|
53
|
+
.optional()
|
|
54
|
+
.openapi({ example: ["branding", "web design"] }),
|
|
55
|
+
experienceLevels: z
|
|
56
|
+
.array(
|
|
57
|
+
z.enum(
|
|
58
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
59
|
+
ExperienceLevel,
|
|
60
|
+
...ExperienceLevel[]
|
|
61
|
+
]
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
.optional()
|
|
65
|
+
.openapi({ example: ["SENIOR", "EXPERT"] }),
|
|
66
|
+
location: z.string().optional().openapi({ example: "Los Angeles" }),
|
|
67
|
+
tags: z
|
|
68
|
+
.array(z.string())
|
|
69
|
+
.optional()
|
|
70
|
+
.openapi({ example: ["Figma", "AI"] }),
|
|
71
|
+
page: z.number().int().min(1).default(1).optional().openapi({ example: 1 }),
|
|
72
|
+
perPage: z
|
|
73
|
+
.number()
|
|
74
|
+
.int()
|
|
75
|
+
.min(1)
|
|
76
|
+
.max(100)
|
|
77
|
+
.default(20)
|
|
78
|
+
.optional()
|
|
79
|
+
.openapi({ example: 20 }),
|
|
80
|
+
})
|
|
81
|
+
.openapi("ListCreativesInput");
|
|
36
82
|
|
|
37
83
|
export const CreateCreativeProfileSchema = z
|
|
38
84
|
.object({
|
|
@@ -101,25 +147,6 @@ export const GetCreativeQuerySchema = ProfileIdentifierSchema;
|
|
|
101
147
|
export const CreateCreativeEndpointResponseSchema = CreativeEntitySchema;
|
|
102
148
|
export const GetCreativeEndpointResponseSchema = CreativeEntitySchema.extend({
|
|
103
149
|
user: MinimalUserSchema,
|
|
104
|
-
})
|
|
150
|
+
});
|
|
105
151
|
export const UpdateCreativeEndpointResponseSchema = CreativeEntitySchema;
|
|
106
152
|
|
|
107
|
-
export type CreateCreativeDto = z.infer<typeof CreateCreativeProfileSchema> & {
|
|
108
|
-
userId: string;
|
|
109
|
-
};
|
|
110
|
-
export type UpdateCreativeDto = z.infer<typeof UpdateCreativeProfileSchema> & {
|
|
111
|
-
userId: string;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export type GetCreativeParams = z.infer<typeof GetCreativeParamsSchema>;
|
|
115
|
-
export type GetCreativeQuery = z.infer<typeof GetCreativeQuerySchema>;
|
|
116
|
-
|
|
117
|
-
export type CreateCreativeEndpointResponse = z.infer<
|
|
118
|
-
typeof CreateCreativeEndpointResponseSchema
|
|
119
|
-
>;
|
|
120
|
-
export type GetCreativeEndpointResponse = z.infer<
|
|
121
|
-
typeof GetCreativeEndpointResponseSchema
|
|
122
|
-
>;
|
|
123
|
-
export type UpdateCreativeEndpointResponse = z.infer<
|
|
124
|
-
typeof UpdateCreativeEndpointResponseSchema
|
|
125
|
-
>;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
import {
|
|
3
|
+
EXPERIENCE_LEVELS,
|
|
4
|
+
ExperienceLevel,
|
|
5
|
+
GEOGRAPHIC_FOCUS,
|
|
6
|
+
GeographicFocus,
|
|
7
|
+
INVESTMENT_SIZES,
|
|
8
|
+
InvestmentSize,
|
|
9
|
+
INVESTOR_TYPES,
|
|
10
|
+
InvestorType,
|
|
11
|
+
} from "../constants";
|
|
12
|
+
import { MinimalUserSchema } from "./user";
|
|
13
|
+
import { CuidSchema, ProfileIdentifierSchema } from "./common";
|
|
14
|
+
|
|
15
|
+
export const InvestorEntitySchema = z
|
|
16
|
+
.object({
|
|
17
|
+
id: z.cuid2().openapi({ example: "inv_cksd0v6q0000s9a5y8z7p3x9" }),
|
|
18
|
+
userId: z.cuid2().openapi({ example: "user_owner_123" }),
|
|
19
|
+
bio: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.openapi({ example: "Early stage VC focusing on creative technology." }),
|
|
23
|
+
location: z.string().optional().openapi({ example: "New York, USA" }),
|
|
24
|
+
experienceLevel: z
|
|
25
|
+
.enum(
|
|
26
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
27
|
+
ExperienceLevel,
|
|
28
|
+
...ExperienceLevel[]
|
|
29
|
+
]
|
|
30
|
+
)
|
|
31
|
+
.optional()
|
|
32
|
+
.openapi({ example: "EXPERT" }),
|
|
33
|
+
geographicFocus: z
|
|
34
|
+
.enum(
|
|
35
|
+
Object.values(GEOGRAPHIC_FOCUS) as [
|
|
36
|
+
GeographicFocus,
|
|
37
|
+
...GeographicFocus[]
|
|
38
|
+
]
|
|
39
|
+
)
|
|
40
|
+
.optional()
|
|
41
|
+
.openapi({ example: "NORTH_AMERICA" }),
|
|
42
|
+
investmentSize: z
|
|
43
|
+
.enum(
|
|
44
|
+
Object.values(INVESTMENT_SIZES) as [InvestmentSize, ...InvestmentSize[]]
|
|
45
|
+
)
|
|
46
|
+
.optional()
|
|
47
|
+
.openapi({ example: "SEED" }),
|
|
48
|
+
investorType: z
|
|
49
|
+
.enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
|
|
50
|
+
.optional()
|
|
51
|
+
.openapi({ example: "VC" }),
|
|
52
|
+
websiteURL: z
|
|
53
|
+
.string()
|
|
54
|
+
.url()
|
|
55
|
+
.optional()
|
|
56
|
+
.openapi({ example: "https://investorpartners.com" }),
|
|
57
|
+
disciplines: z
|
|
58
|
+
.array(z.string())
|
|
59
|
+
.optional()
|
|
60
|
+
.openapi({ example: ["Product Design", "AI Strategy"] }),
|
|
61
|
+
createdAt: z
|
|
62
|
+
.string()
|
|
63
|
+
.datetime()
|
|
64
|
+
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
65
|
+
updatedAt: z
|
|
66
|
+
.string()
|
|
67
|
+
.datetime()
|
|
68
|
+
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
69
|
+
})
|
|
70
|
+
.openapi("InvestorEntity");
|
|
71
|
+
|
|
72
|
+
export const InvestorWithUserEntitySchema = InvestorEntitySchema.extend({
|
|
73
|
+
user: MinimalUserSchema,
|
|
74
|
+
disciplines: z
|
|
75
|
+
.array(z.string())
|
|
76
|
+
.openapi({ example: ["Product Design", "AI Strategy"] }),
|
|
77
|
+
}).openapi("InvestorWithUserEntity");
|
|
78
|
+
|
|
79
|
+
export const CreateInvestorProfileSchema = z
|
|
80
|
+
.object({
|
|
81
|
+
bio: z.string().max(210).optional().default("").openapi({
|
|
82
|
+
example: "Angel investor backing early-stage African startups.",
|
|
83
|
+
}),
|
|
84
|
+
websiteURL: z.string().url("Invalid url").optional().openapi({
|
|
85
|
+
example: "https://www.investorportfolio.com",
|
|
86
|
+
}),
|
|
87
|
+
experienceLevel: z
|
|
88
|
+
.enum(
|
|
89
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
90
|
+
ExperienceLevel,
|
|
91
|
+
...ExperienceLevel[]
|
|
92
|
+
]
|
|
93
|
+
)
|
|
94
|
+
.default(EXPERIENCE_LEVELS.YEAR_0_1)
|
|
95
|
+
.openapi({
|
|
96
|
+
example: "0-1 year",
|
|
97
|
+
}),
|
|
98
|
+
location: z.string().openapi({
|
|
99
|
+
example: "UK",
|
|
100
|
+
}),
|
|
101
|
+
})
|
|
102
|
+
.openapi({
|
|
103
|
+
title: "Create Investor Profile",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export const UpdateInvestorProfileSchema = z
|
|
107
|
+
.object({
|
|
108
|
+
bio: z.string().max(210).optional().openapi({
|
|
109
|
+
example: "Seasoned venture capitalist with a focus on healthtech.",
|
|
110
|
+
}),
|
|
111
|
+
websiteURL: z.string().url("Invalid url").optional().openapi({
|
|
112
|
+
example: "https://www.vcgroup.com",
|
|
113
|
+
}),
|
|
114
|
+
experienceLevel: z
|
|
115
|
+
.enum(
|
|
116
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
117
|
+
ExperienceLevel,
|
|
118
|
+
...ExperienceLevel[]
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
.optional()
|
|
122
|
+
.openapi({
|
|
123
|
+
example: "SENIOR",
|
|
124
|
+
}),
|
|
125
|
+
investorType: z
|
|
126
|
+
.enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
|
|
127
|
+
.optional()
|
|
128
|
+
.openapi({
|
|
129
|
+
example: "VC",
|
|
130
|
+
}),
|
|
131
|
+
disciplineSlugs: z
|
|
132
|
+
.array(z.string())
|
|
133
|
+
.min(1, "At least one discipline is required")
|
|
134
|
+
.optional()
|
|
135
|
+
.openapi({
|
|
136
|
+
example: ["fintech", "edtech"],
|
|
137
|
+
}),
|
|
138
|
+
investmentSize: z
|
|
139
|
+
.enum(
|
|
140
|
+
Object.values(INVESTMENT_SIZES) as [InvestmentSize, ...InvestmentSize[]]
|
|
141
|
+
)
|
|
142
|
+
.optional()
|
|
143
|
+
.openapi({
|
|
144
|
+
example: "SEED",
|
|
145
|
+
}),
|
|
146
|
+
geographicFocus: z
|
|
147
|
+
.enum(
|
|
148
|
+
Object.values(GEOGRAPHIC_FOCUS) as [
|
|
149
|
+
GeographicFocus,
|
|
150
|
+
...GeographicFocus[]
|
|
151
|
+
]
|
|
152
|
+
)
|
|
153
|
+
.optional()
|
|
154
|
+
.openapi({
|
|
155
|
+
example: "GLOBAL",
|
|
156
|
+
}),
|
|
157
|
+
location: z.string().optional().openapi({
|
|
158
|
+
example: "UK",
|
|
159
|
+
}),
|
|
160
|
+
})
|
|
161
|
+
.openapi({
|
|
162
|
+
title: "Update Investor Profile",
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
export const ListInvestorsInputSchema = z
|
|
166
|
+
.object({
|
|
167
|
+
query: z.string().optional().openapi({ example: "creative tech investor" }),
|
|
168
|
+
disciplines: z
|
|
169
|
+
.array(z.string())
|
|
170
|
+
.optional()
|
|
171
|
+
.openapi({ example: ["branding", "UX"] }),
|
|
172
|
+
experienceLevels: z
|
|
173
|
+
.array(
|
|
174
|
+
z.enum(
|
|
175
|
+
Object.values(EXPERIENCE_LEVELS) as [
|
|
176
|
+
ExperienceLevel,
|
|
177
|
+
...ExperienceLevel[]
|
|
178
|
+
]
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
.optional()
|
|
182
|
+
.openapi({
|
|
183
|
+
description: "Filter based on the required experience level.",
|
|
184
|
+
}),
|
|
185
|
+
location: z.string().optional().openapi({ example: "San Francisco" }),
|
|
186
|
+
tags: z
|
|
187
|
+
.array(z.string())
|
|
188
|
+
.optional()
|
|
189
|
+
.openapi({ example: ["design", "future"] }),
|
|
190
|
+
page: z.number().int().min(1).default(1).optional().openapi({ example: 1 }),
|
|
191
|
+
perPage: z
|
|
192
|
+
.number()
|
|
193
|
+
.int()
|
|
194
|
+
.min(1)
|
|
195
|
+
.max(100)
|
|
196
|
+
.default(20)
|
|
197
|
+
.optional()
|
|
198
|
+
.openapi({ example: 20 }),
|
|
199
|
+
})
|
|
200
|
+
.openapi("ListInvestorsInput");
|
|
201
|
+
|
|
202
|
+
export const GetInvestorParamsSchema = z.object({
|
|
203
|
+
value: CuidSchema,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
export const GetInvestorQuerySchema = ProfileIdentifierSchema;
|
|
207
|
+
|
|
208
|
+
export const CreateInvestorEndpointResponseSchema = InvestorEntitySchema;
|
|
209
|
+
export const GetInvestorEndpointResponseSchema = InvestorEntitySchema.extend({
|
|
210
|
+
user: MinimalUserSchema,
|
|
211
|
+
});
|
|
212
|
+
export const UpdateInvestorEndpointResponseSchema = InvestorEntitySchema;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
import { CLIENT_TYPES, ClientType, Role, ROLES } from "../constants";
|
|
3
|
+
|
|
4
|
+
export const ProjectEntitySchema = z
|
|
5
|
+
.object({
|
|
6
|
+
id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
|
|
7
|
+
createdAt: z.iso
|
|
8
|
+
.datetime()
|
|
9
|
+
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
10
|
+
updatedAt: z.iso
|
|
11
|
+
.datetime()
|
|
12
|
+
.openapi({ example: "2025-10-13T09:00:00.000Z" }),
|
|
13
|
+
userId: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
|
|
14
|
+
title: z.string().openapi({ example: "Brand Identity Design" }),
|
|
15
|
+
description: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.openapi({ example: "A full rebrand for a fashion label." }),
|
|
19
|
+
overview: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.openapi({ example: "Detailed project story and outcomes." }),
|
|
23
|
+
url: z
|
|
24
|
+
.string()
|
|
25
|
+
.url()
|
|
26
|
+
.optional()
|
|
27
|
+
.openapi({ example: "https://example.com/project" }),
|
|
28
|
+
clientId: z.string().optional().openapi({ example: "client_abc123" }),
|
|
29
|
+
clientType: z
|
|
30
|
+
.enum(Object.values(CLIENT_TYPES) as [ClientType, ...ClientType[]])
|
|
31
|
+
.optional()
|
|
32
|
+
.openapi({ example: "BRAND" }),
|
|
33
|
+
clientName: z.string().optional().openapi({ example: "Nike" }),
|
|
34
|
+
projectCreatorType: z
|
|
35
|
+
.enum(Object.values(ROLES) as [Role, ...Role[]])
|
|
36
|
+
.openapi({ example: "CREATIVE" }),
|
|
37
|
+
tags: z
|
|
38
|
+
.array(z.string())
|
|
39
|
+
.optional()
|
|
40
|
+
.openapi({ example: ["branding", "logo"] }),
|
|
41
|
+
isFeatured: z.boolean().optional().openapi({ example: false }),
|
|
42
|
+
startDate: z.iso
|
|
43
|
+
.datetime()
|
|
44
|
+
.optional()
|
|
45
|
+
.openapi({ example: "2025-06-01T00:00:00.000Z" }),
|
|
46
|
+
endDate: z.iso
|
|
47
|
+
.datetime()
|
|
48
|
+
.optional()
|
|
49
|
+
.openapi({ example: "2025-07-15T00:00:00.000Z" }),
|
|
50
|
+
imagePlaceholderUrl: z
|
|
51
|
+
.string()
|
|
52
|
+
.url()
|
|
53
|
+
.optional()
|
|
54
|
+
.openapi({ example: "https://example.com/project-image.png" }),
|
|
55
|
+
})
|
|
56
|
+
.openapi("ProjectEntity");
|
|
57
|
+
|
|
58
|
+
export const ProjectFileEntitySchema = z
|
|
59
|
+
.object({
|
|
60
|
+
id: z.cuid2().openapi({ example: "pfe_cksd0v6q0000s9a5y8z7p3x9" }),
|
|
61
|
+
projectId: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
|
|
62
|
+
url: z
|
|
63
|
+
.string()
|
|
64
|
+
.url()
|
|
65
|
+
.openapi({ example: "https://cdn.example.com/project/image.jpg" }),
|
|
66
|
+
mimeType: z.string().openapi({ example: "image/jpeg" }),
|
|
67
|
+
fileSize: z.number().int().positive().openapi({ example: 1500000 }), // size in bytes
|
|
68
|
+
})
|
|
69
|
+
.openapi("ProjectFileEntity");
|
|
70
|
+
|
|
71
|
+
export const ProjectSocialGraphEntitySchema = z
|
|
72
|
+
.object({
|
|
73
|
+
noOfLikes: z.number().int().optional().openapi({ example: 150 }),
|
|
74
|
+
noOfComments: z.number().int().optional().openapi({ example: 45 }),
|
|
75
|
+
noOfBookmarks: z.number().int().optional().openapi({ example: 22 }),
|
|
76
|
+
noOfViews: z.number().int().optional().openapi({ example: 1200 }),
|
|
77
|
+
})
|
|
78
|
+
.openapi("ProjectSocialGraphEntity");
|
|
79
|
+
|
|
80
|
+
export const UserSocialGraphEntitySchema = z
|
|
81
|
+
.object({
|
|
82
|
+
followerCount: z.number().int().optional().openapi({ example: 5000 }),
|
|
83
|
+
followingCount: z.number().int().optional().openapi({ example: 150 }),
|
|
84
|
+
})
|
|
85
|
+
.openapi("UserSocialGraphEntity");
|
|
86
|
+
|
|
87
|
+
export const ProjectWithFilesEntitySchema = ProjectEntitySchema.merge(
|
|
88
|
+
ProjectSocialGraphEntitySchema
|
|
89
|
+
)
|
|
90
|
+
.extend({
|
|
91
|
+
projectFiles: z
|
|
92
|
+
.array(ProjectFileEntitySchema)
|
|
93
|
+
.optional()
|
|
94
|
+
.openapi({ description: "Files associated with the project" }),
|
|
95
|
+
})
|
|
96
|
+
.openapi("ProjectWithFilesEntity");
|
|
97
|
+
|
|
98
|
+
export const ProjectViewEntitySchema = z
|
|
99
|
+
.object({
|
|
100
|
+
id: z.cuid2().openapi({ example: "view_cksd0v6q0000s9a5y8z7p3x9" }),
|
|
101
|
+
userId: z.cuid2().optional().openapi({ example: "user_view_xyz" }),
|
|
102
|
+
ipAddress: z.ipv4().optional().openapi({ example: "192.168.1.1" }),
|
|
103
|
+
userAgent: z
|
|
104
|
+
.string()
|
|
105
|
+
.optional()
|
|
106
|
+
.openapi({ example: "Mozilla/5.0 (Windows NT 10.0; Win64)" }),
|
|
107
|
+
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
108
|
+
sessionId: z.string().optional().openapi({ example: "sess_xyz789" }),
|
|
109
|
+
viewedAt: z.iso.datetime().openapi({ example: "2025-10-14T10:30:00.000Z" }),
|
|
110
|
+
viewDate: z.iso.datetime().openapi({ example: "2025-10-14T00:00:00.000Z" }),
|
|
111
|
+
})
|
|
112
|
+
.openapi("ProjectViewEntity");
|
|
113
|
+
|
|
114
|
+
export const ProjectLikeEntitySchema = z
|
|
115
|
+
.object({
|
|
116
|
+
createdAt: z.iso
|
|
117
|
+
.datetime()
|
|
118
|
+
.openapi({ example: "2025-10-13T11:00:00.000Z" }),
|
|
119
|
+
userId: z.cuid2().openapi({ example: "user_liker_123" }),
|
|
120
|
+
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
121
|
+
})
|
|
122
|
+
.openapi("ProjectLikeEntity");
|
|
123
|
+
|
|
124
|
+
export const ProjectCommentEntitySchema = z
|
|
125
|
+
.object({
|
|
126
|
+
id: z.cuid2().openapi({ example: "comment_id_1" }),
|
|
127
|
+
createdAt: z.iso
|
|
128
|
+
.datetime()
|
|
129
|
+
.openapi({ example: "2025-10-13T12:00:00.000Z" }),
|
|
130
|
+
userId: z.cuid2().openapi({ example: "user_commenter_456" }),
|
|
131
|
+
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
132
|
+
parentCommentId: z
|
|
133
|
+
.cuid2()
|
|
134
|
+
.optional()
|
|
135
|
+
.openapi({ example: "comment_id_parent_1" }),
|
|
136
|
+
content: z
|
|
137
|
+
.string()
|
|
138
|
+
.min(1)
|
|
139
|
+
.openapi({ example: "Amazing work on the color palette!" }),
|
|
140
|
+
})
|
|
141
|
+
.openapi("ProjectCommentEntity");
|
|
142
|
+
|
|
143
|
+
export const ProjectBookmarkEntitySchema = z
|
|
144
|
+
.object({
|
|
145
|
+
createdAt: z.iso
|
|
146
|
+
.datetime()
|
|
147
|
+
.openapi({ example: "2025-10-13T13:00:00.000Z" }),
|
|
148
|
+
userId: z.cuid2().openapi({ example: "user_bookmark_789" }),
|
|
149
|
+
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
150
|
+
})
|
|
151
|
+
.openapi("ProjectBookmarkEntity");
|
|
152
|
+
|
|
153
|
+
// =================================================================
|
|
154
|
+
// 5. Output Schemas
|
|
155
|
+
// =================================================================
|
|
156
|
+
|
|
157
|
+
export const ProjectUpdateOutputEntitySchema = z
|
|
158
|
+
.object({
|
|
159
|
+
id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
|
|
160
|
+
})
|
|
161
|
+
.openapi("ProjectUpdateOutputEntity");
|