devfolio-page 0.2.2 → 0.2.4

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.
@@ -95,59 +95,59 @@ const contentSectionSchema = z.discriminatedUnion('type', [
95
95
  // Simple project schema (backwards compatible)
96
96
  const simpleProjectSchema = z.object({
97
97
  name: z.string().min(1, 'Project name is required'),
98
- url: urlString.optional(),
99
- description: z.string().min(1, 'Project description is required'),
100
- tags: z.array(z.string()).min(1, 'At least one tag is required'),
101
- featured: z.boolean().optional(),
98
+ url: urlString.optional().nullable(),
99
+ description: z.string().optional().nullable(),
100
+ tags: z.array(z.string()).optional().nullable(),
101
+ featured: z.boolean().optional().nullable(),
102
102
  });
103
103
  // Rich project schema (for case studies)
104
104
  const richProjectSchema = z.object({
105
105
  id: z.string().min(1, 'Project ID (URL slug) is required'),
106
106
  title: z.string().min(1, 'Project title is required'),
107
- subtitle: z.string().optional(),
108
- featured: z.boolean().optional(),
109
- thumbnail: urlOrPath.optional(),
110
- hero: urlOrPath.optional(),
107
+ subtitle: z.string().optional().nullable(),
108
+ featured: z.boolean().optional().nullable(),
109
+ thumbnail: urlOrPath.optional().nullable(),
110
+ hero: urlOrPath.optional().nullable(),
111
111
  meta: z.object({
112
- year: z.union([z.string(), z.number()]),
113
- role: z.string().min(1, 'Role is required'),
114
- timeline: z.string().optional(),
115
- tech: z.array(z.string()).min(1, 'At least one technology is required'),
112
+ year: z.union([z.string(), z.number()]).optional().nullable(),
113
+ role: z.string().optional().nullable(),
114
+ timeline: z.string().optional().nullable(),
115
+ tech: z.array(z.string()).optional().nullable(),
116
116
  links: z
117
117
  .object({
118
- github: urlString.optional(),
119
- demo: urlString.optional(),
120
- live: urlString.optional(),
121
- case_study: urlString.optional(),
118
+ github: urlString.optional().nullable(),
119
+ demo: urlString.optional().nullable(),
120
+ live: urlString.optional().nullable(),
121
+ case_study: urlString.optional().nullable(),
122
122
  })
123
- .optional(),
124
- }),
125
- sections: z.array(contentSectionSchema).min(1, 'At least one section is required'),
123
+ .optional().nullable(),
124
+ }).optional().nullable(),
125
+ sections: z.array(contentSectionSchema).optional().nullable(),
126
126
  });
127
127
  // =============================================================================
128
128
  // Experience & Education Schemas
129
129
  // =============================================================================
130
130
  const experienceSchema = z.object({
131
131
  company: z.string().min(1, 'Company name is required'),
132
- role: z.string().min(1, 'Role is required'),
132
+ role: z.string().optional().nullable(),
133
133
  date: z.object({
134
- start: dateFormat,
135
- end: dateOrPresent,
136
- }),
137
- location: z.string().optional(),
138
- description: z.string().optional(),
139
- highlights: z.array(z.string()).min(1, 'At least one highlight is required'),
134
+ start: dateFormat.optional().nullable(),
135
+ end: dateOrPresent.optional().nullable(),
136
+ }).optional().nullable(),
137
+ location: z.string().optional().nullable(),
138
+ description: z.string().optional().nullable(),
139
+ highlights: z.array(z.string()).optional().nullable(),
140
140
  });
141
141
  const educationSchema = z.object({
142
142
  institution: z.string().min(1, 'Institution name is required'),
143
- degree: z.string().min(1, 'Degree is required'),
143
+ degree: z.string().optional().nullable(),
144
144
  date: z.object({
145
- start: dateFormat,
146
- end: dateFormat,
147
- }),
148
- location: z.string().optional(),
149
- description: z.string().optional(),
150
- highlights: z.array(z.string()).optional(),
145
+ start: dateFormat.optional().nullable(),
146
+ end: dateFormat.optional().nullable(),
147
+ }).optional().nullable(),
148
+ location: z.string().optional().nullable(),
149
+ description: z.string().optional().nullable(),
150
+ highlights: z.array(z.string()).optional().nullable(),
151
151
  });
152
152
  // =============================================================================
153
153
  // Skills Schemas
@@ -172,38 +172,38 @@ const richSkillsSchema = z.object({
172
172
  // =============================================================================
173
173
  const writingSchema = z.object({
174
174
  title: z.string().min(1, 'Article title is required'),
175
- url: urlString,
176
- date: dateFormat,
177
- description: z.string().optional(), // Backwards compatible
178
- excerpt: z.string().optional(),
179
- cover: urlOrPath.optional(),
180
- publication: z.string().optional(),
181
- tags: z.array(z.string()).optional(),
182
- featured: z.boolean().optional(),
175
+ url: urlString.optional().nullable(),
176
+ date: dateFormat.optional().nullable(),
177
+ description: z.string().optional().nullable(),
178
+ excerpt: z.string().optional().nullable(),
179
+ cover: urlOrPath.optional().nullable(),
180
+ publication: z.string().optional().nullable(),
181
+ tags: z.array(z.string()).optional().nullable(),
182
+ featured: z.boolean().optional().nullable(),
183
183
  });
184
184
  // =============================================================================
185
185
  // New Content Types
186
186
  // =============================================================================
187
187
  const experimentSchema = z.object({
188
188
  title: z.string().min(1, 'Experiment title is required'),
189
- description: z.string().min(1, 'Experiment description is required'),
190
- image: urlOrPath.optional(),
191
- github: urlString.optional(),
192
- demo: urlString.optional(),
193
- tags: z.array(z.string()).min(1, 'At least one tag is required'),
189
+ description: z.string().optional().nullable(),
190
+ image: urlOrPath.optional().nullable(),
191
+ github: urlString.optional().nullable(),
192
+ demo: urlString.optional().nullable(),
193
+ tags: z.array(z.string()).optional().nullable(),
194
194
  });
195
195
  const testimonialSchema = z.object({
196
196
  quote: z.string().min(1, 'Quote is required'),
197
- author: z.string().min(1, 'Author name is required'),
198
- company: z.string().optional(),
199
- role: z.string().optional(),
200
- image: urlOrPath.optional(),
197
+ author: z.string().optional().nullable(),
198
+ company: z.string().optional().nullable(),
199
+ role: z.string().optional().nullable(),
200
+ image: urlOrPath.optional().nullable(),
201
201
  });
202
202
  const timelineItemSchema = z.object({
203
- year: z.union([z.string(), z.number()]),
203
+ year: z.union([z.string(), z.number()]).optional().nullable(),
204
204
  title: z.string().min(1, 'Timeline item title is required'),
205
- description: z.string().min(1, 'Timeline item description is required'),
206
- image: urlOrPath.optional(),
205
+ description: z.string().optional().nullable(),
206
+ image: urlOrPath.optional().nullable(),
207
207
  });
208
208
  // =============================================================================
209
209
  // Settings & Layout Schemas
@@ -227,50 +227,50 @@ export const portfolioSchema = z.object({
227
227
  // Core metadata
228
228
  meta: z.object({
229
229
  name: z.string().min(1, 'Name is required'),
230
- title: z.string().min(1, 'Professional title is required'),
231
- tagline: z.string().optional(),
232
- location: z.string().min(1, 'Location is required'),
233
- timezone: z.string().optional(),
234
- avatar: urlOrPath.optional(),
235
- hero_image: urlOrPath.optional(),
230
+ title: z.string().optional().nullable(),
231
+ tagline: z.string().optional().nullable(),
232
+ location: z.string().optional().nullable(),
233
+ timezone: z.string().optional().nullable(),
234
+ avatar: urlOrPath.optional().nullable(),
235
+ hero_image: urlOrPath.optional().nullable(),
236
236
  }),
237
237
  // Contact information
238
238
  contact: z.object({
239
- email: z.string().email('Must be a valid email address'),
240
- website: urlString.optional(),
241
- github: z.string().optional(),
242
- linkedin: z.string().optional(),
243
- twitter: z.string().optional(),
244
- }),
245
- // Bio (required for backwards compatibility)
246
- bio: z.string().min(10, 'Bio should be at least 10 characters'),
239
+ email: z.string().email('Must be a valid email address').optional().nullable(),
240
+ website: urlString.optional().nullable(),
241
+ github: z.string().optional().nullable(),
242
+ linkedin: z.string().optional().nullable(),
243
+ twitter: z.string().optional().nullable(),
244
+ }).optional().nullable(),
245
+ // Bio
246
+ bio: z.string().optional().nullable(),
247
247
  // Extended about section (optional)
248
248
  about: z
249
249
  .object({
250
- short: z.string().min(1, 'Short bio is required'),
251
- long: z.string().min(1, 'Long bio is required'),
250
+ short: z.string().optional().nullable(),
251
+ long: z.string().optional().nullable(),
252
252
  })
253
- .optional(),
253
+ .optional().nullable(),
254
254
  // Sections (backwards compatible structure)
255
255
  sections: z.object({
256
- experience: z.array(experienceSchema).optional(),
257
- projects: z.array(simpleProjectSchema).optional(),
258
- skills: simpleSkillsSchema.optional(),
259
- writing: z.array(writingSchema).optional(),
260
- education: z.array(educationSchema).optional(),
261
- }),
256
+ experience: z.array(experienceSchema).optional().nullable(),
257
+ projects: z.array(simpleProjectSchema).optional().nullable(),
258
+ skills: simpleSkillsSchema.optional().nullable(),
259
+ writing: z.array(writingSchema).optional().nullable(),
260
+ education: z.array(educationSchema).optional().nullable(),
261
+ }).optional().nullable(),
262
262
  // Rich projects (new structure for case studies)
263
- projects: z.array(richProjectSchema).optional(),
263
+ projects: z.array(richProjectSchema).optional().nullable(),
264
264
  // New content types
265
- experiments: z.array(experimentSchema).optional(),
266
- testimonials: z.array(testimonialSchema).optional(),
267
- timeline: z.array(timelineItemSchema).optional(),
265
+ experiments: z.array(experimentSchema).optional().nullable(),
266
+ testimonials: z.array(testimonialSchema).optional().nullable(),
267
+ timeline: z.array(timelineItemSchema).optional().nullable(),
268
268
  // Theme selection
269
- theme: z.enum(['srcl', 'modern', 'minimal', 'dark-academia']).optional(),
269
+ theme: z.enum(['srcl', 'modern', 'minimal', 'dark-academia']).optional().nullable(),
270
270
  // Layout configuration
271
- layout: layoutSchema.optional(),
271
+ layout: layoutSchema.optional().nullable(),
272
272
  // Settings
273
- settings: settingsSchema.optional(),
273
+ settings: settingsSchema.optional().nullable(),
274
274
  });
275
275
  // =============================================================================
276
276
  // Helper Functions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devfolio-page",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Your portfolio as code. Version control it like software.",
5
5
  "type": "module",
6
6
  "bin": {