# All files / src/schemas/ep common.ts

100% Statements 10/10
100% Branches 4/4
100% Functions 2/2
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85

    59x

    59x

    59x

    59x

    360x
    65x

    295x

    59x

    59x

    75x

     /**
     * Shared validation primitives used across all EP schema modules.
     *
     * @module schemas/ep/common
     */

    import { z } from 'zod';

    /**
     * ISO 3166-1 alpha-2 country code validation
     */
    export const CountryCodeSchema = z.string()
      .length(2)
      .regex(/^[A-Z]{2}$/, 'Country code must be 2 uppercase letters')
      .describe('ISO 3166-1 alpha-2 country code (e.g., "SE")');

    /**
     * Date validation (YYYY-MM-DD format)
     */
    export const DateStringSchema = z.string()
      .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format')
      .describe('Date in YYYY-MM-DD format');

    /**
     * MEP identifier validation.
     * Accepts numeric IDs, "MEP-{number}", or "person/{number}" formats.
     */
    export const MepIdSchema = z.string()
      .min(1)
      .max(100)
      .regex(
        /^(?:\d+|MEP-\d+|person\/\d+)$/,
        'MEP ID must be numeric, "MEP-{number}", or "person/{number}"'
      )
      .describe('MEP identifier');

    /**
     * Session identifier validation.
     * Accepts alphanumeric characters with hyphens and underscores.
     */
    export const SessionIdSchema = z.string()
      .min(1)
      .max(100)
      .regex(
        /^[a-zA-Z0-9\-_]+$/,
        'Session ID must be alphanumeric with hyphens and underscores'
      )
      .describe('Plenary session identifier');

    /**
     * Cross-field date range refinement helper.
     * Ensures dateFrom is before or equal to dateTo when both are provided.
     */
    export function refineDateRange(
      data: { dateFrom?: string | undefined; dateTo?: string | undefined }
    ): boolean {
      if (data.dateFrom !== undefined && data.dateTo !== undefined) {
        return data.dateFrom <= data.dateTo;
      }
      return true;
    }

    /** Error message for invalid date ranges */
    export const DATE_RANGE_ERROR = 'dateFrom must be before or equal to dateTo';

    /**
     * Paginated response schema factory
     */
    export const PaginatedResponseSchema = <T extends z.ZodType>(
      dataSchema: T
    ): z.ZodObject<{
      data: z.ZodArray<T>;
      total: z.ZodNumber;
      limit: z.ZodNumber;
      offset: z.ZodNumber;
      hasMore: z.ZodBoolean;
    }> =>
      z.object({
        data: z.array(dataSchema),
        total: z.number().int().min(0),
        limit: z.number().int().min(1),
        offset: z.number().int().min(0),
        hasMore: z.boolean()
      });