Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/modules/creator/creator-profile.schemas.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { z } from 'zod';
import { withCreatorSlugEmptyStringNormalization } from './creator-slug-input.utils';

/**
* Shared creator profile identifier schema for route params.
Expand All @@ -7,11 +8,13 @@ import { z } from 'zod';
* and keep this centralized for future route extensions.
*/
export const CreatorProfileParamsSchema = z.object({
creatorId: z
.string()
.trim()
.min(1, 'Creator ID is required')
.max(128, 'Creator ID is too long'),
creatorId: withCreatorSlugEmptyStringNormalization(
z
.string()
.trim()
.min(1, 'Creator ID is required')
.max(128, 'Creator ID is too long')
),
});

/**
Expand Down Expand Up @@ -50,7 +53,11 @@ export const UpsertCreatorProfileBodySchema = z.object({
.trim()
.max(1000, 'Bio must be at most 1000 characters')
.optional(),
avatarUrl: z.string().trim().url('Avatar URL must be a valid URL').optional(),
avatarUrl: z
.string()
.trim()
.url('Avatar URL must be a valid URL')
.optional(),
links: z
.array(
z.object({
Expand Down
36 changes: 36 additions & 0 deletions src/modules/creator/creator-slug-input.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { z, ZodTypeAny } from 'zod';

/**
* Normalizes creator slug route input before validation.
*
* Scope is intentionally narrow:
* - exact empty-string input becomes `undefined`
* - `null` / `undefined` become `undefined`
* - all other values pass through unchanged
*
* This lets creator route schemas treat empty-string slug params the same way
* as omitted params without introducing broader slug rewriting behavior.
*/
export function normalizeCreatorSlugEmptyString(value: unknown): unknown {
if (value === null || value === undefined) {
return undefined;
}

if (value === '') {
return undefined;
}

return value;
}

/**
* Wraps a Zod schema with {@link normalizeCreatorSlugEmptyString} preprocessing.
*
* Use for creator route params that may receive slug-shaped input from HTTP
* layers before the actual route schema runs.
*/
export function withCreatorSlugEmptyStringNormalization<T extends ZodTypeAny>(
schema: T
) {
return z.preprocess(normalizeCreatorSlugEmptyString, schema);
}
Loading