@kaiord/core / workoutSchema
Variable: workoutSchema
constworkoutSchema:ZodObject<{extensions:ZodOptional<ZodRecord<ZodString,ZodUnknown>>;name:ZodOptional<ZodString>;poolLength:ZodOptional<ZodNumber>;poolLengthUnit:ZodOptional<ZodLiteral<"meters">>;sport:ZodEnum<{alpine_skiing:"alpine_skiing";american_football:"american_football";archery:"archery";baseball:"baseball";basketball:"basketball";boating:"boating";boxing:"boxing";canoeing:"canoeing";cricket:"cricket";cross_country_skiing:"cross_country_skiing";cycling:"cycling";dance:"dance";disc_golf:"disc_golf";diving:"diving";driving:"driving";e_biking:"e_biking";fishing:"fishing";fitness_equipment:"fitness_equipment";floor_climbing:"floor_climbing";flying:"flying";generic:"generic";geocaching:"geocaching";golf:"golf";grinding:"grinding";hang_gliding:"hang_gliding";hiit:"hiit";hiking:"hiking";hockey:"hockey";horseback_riding:"horseback_riding";hunting:"hunting";ice_skating:"ice_skating";inline_skating:"inline_skating";jump_rope:"jump_rope";jumpmaster:"jumpmaster";kayaking:"kayaking";kitesurfing:"kitesurfing";lacrosse:"lacrosse";meditation:"meditation";mixed_martial_arts:"mixed_martial_arts";mobility:"mobility";motor_sports:"motor_sports";motorcycling:"motorcycling";mountaineering:"mountaineering";multisport:"multisport";paddling:"paddling";para_sport:"para_sport";pool_apnea:"pool_apnea";racket:"racket";rafting:"rafting";rock_climbing:"rock_climbing";rowing:"rowing";rugby:"rugby";running:"running";sailing:"sailing";shooting:"shooting";sky_diving:"sky_diving";snorkeling:"snorkeling";snowboarding:"snowboarding";snowmobiling:"snowmobiling";snowshoeing:"snowshoeing";soccer:"soccer";stand_up_paddleboarding:"stand_up_paddleboarding";surfing:"surfing";swimming:"swimming";tactical:"tactical";team_sport:"team_sport";tennis:"tennis";training:"training";transition:"transition";video_gaming:"video_gaming";volleyball:"volleyball";wakeboarding:"wakeboarding";wakesurfing:"wakesurfing";walking:"walking";water_skiing:"water_skiing";water_sport:"water_sport";water_tubing:"water_tubing";wheelchair_push_run:"wheelchair_push_run";wheelchair_push_walk:"wheelchair_push_walk";windsurfing:"windsurfing";winter_sport:"winter_sport"; }>;steps:ZodArray<ZodUnion<readonly [ZodObject<{duration:ZodDiscriminatedUnion<[ZodObject<{seconds: ...;type: ...; },$strip>,ZodObject<{meters: ...;type: ...; },$strip>,ZodObject<{bpm: ...;type: ...; },$strip>,ZodObject<{bpm: ...;repeatFrom: ...;type: ...; },$strip>],"type">;durationType:ZodEnum<{calories:"calories";distance:"distance";heart_rate_less_than:"heart_rate_less_than";open:"open";power_greater_than:"power_greater_than";power_less_than:"power_less_than";repeat_until_calories:"repeat_until_calories";repeat_until_distance:"repeat_until_distance";repeat_until_heart_rate_greater_than:"repeat_until_heart_rate_greater_than";repeat_until_heart_rate_less_than:"repeat_until_heart_rate_less_than";repeat_until_power_greater_than:"repeat_until_power_greater_than";repeat_until_power_less_than:"repeat_until_power_less_than";repeat_until_time:"repeat_until_time";time:"time"; }>;equipment:ZodOptional<ZodEnum<{none:"none";swim_fins:"swim_fins";swim_kickboard:"swim_kickboard";swim_paddles:"swim_paddles";swim_pull_buoy:"swim_pull_buoy";swim_snorkel:"swim_snorkel"; }>>;extensions:ZodOptional<ZodRecord<ZodString,ZodUnknown>>;intensity:ZodOptional<ZodEnum<{active:"active";cooldown:"cooldown";interval:"interval";other:"other";recovery:"recovery";rest:"rest";warmup:"warmup"; }>>;name:ZodOptional<ZodString>;notes:ZodOptional<ZodString>;stepIndex:ZodNumber;target:ZodDiscriminatedUnion<[ZodObject<{type: ...;value: ...; },$strip>,ZodObject<{type: ...;value: ...; },$strip>,ZodObject<{type: ...;value: ...; },$strip>],"type">;targetType:ZodEnum<{cadence:"cadence";heart_rate:"heart_rate";open:"open";pace:"pace";power:"power";stroke_type:"stroke_type"; }>; },$strip>,ZodObject<{id:ZodOptional<ZodString>;repeatCount:ZodNumber;steps:ZodArray<ZodObject<{duration:ZodDiscriminatedUnion<..., ...>;durationType:ZodEnum<...>;equipment:ZodOptional<...>;extensions:ZodOptional<...>;intensity:ZodOptional<...>;name:ZodOptional<...>;notes:ZodOptional<...>;stepIndex:ZodNumber;target:ZodDiscriminatedUnion<..., ...>;targetType:ZodEnum<...>; },$strip>>; },$strip>]>>;subSport:ZodOptional<ZodEnum<{all:"all";apnea_diving:"apnea_diving";apnea_hunting:"apnea_hunting";atv:"atv";backcountry:"backcountry";bike_to_run_transition:"bike_to_run_transition";bmx:"bmx";cardio_training:"cardio_training";casual_walking:"casual_walking";challenge:"challenge";commuting:"commuting";cyclocross:"cyclocross";downhill:"downhill";e_bike_fitness:"e_bike_fitness";e_bike_mountain:"e_bike_mountain";elliptical:"elliptical";exercise:"exercise";flexibility_training:"flexibility_training";gauge_diving:"gauge_diving";generic:"generic";gravel_cycling:"gravel_cycling";hand_cycling:"hand_cycling";indoor_cycling:"indoor_cycling";indoor_rowing:"indoor_rowing";indoor_running:"indoor_running";indoor_skiing:"indoor_skiing";indoor_walking:"indoor_walking";lap_swimming:"lap_swimming";map:"map";match:"match";mixed_surface:"mixed_surface";motocross:"motocross";mountain:"mountain";multi_gas_diving:"multi_gas_diving";navigate:"navigate";obstacle:"obstacle";open_water:"open_water";pilates:"pilates";rc_drone:"rc_drone";recumbent:"recumbent";resort:"resort";road:"road";run_to_bike_transition:"run_to_bike_transition";single_gas_diving:"single_gas_diving";skate_skiing:"skate_skiing";speed_walking:"speed_walking";spin:"spin";stair_climbing:"stair_climbing";street:"street";strength_training:"strength_training";swim_to_bike_transition:"swim_to_bike_transition";track:"track";track_cycling:"track_cycling";track_me:"track_me";trail:"trail";treadmill:"treadmill";virtual_activity:"virtual_activity";warm_up:"warm_up";whitewater:"whitewater";wingsuit:"wingsuit";yoga:"yoga"; }>>; },$strip>
Defined in: packages/core/src/domain/schemas/workout.ts:41
Zod schema for a complete workout definition.
Validates a structured workout with metadata and a sequence of steps or repetition blocks.
stepIndex values on steps are advisory ordering metadata: producers SHOULD emit 0-based contiguous indices, but the schema deliberately does not enforce contiguity or uniqueness — adapters renumber steps when flattening repetition blocks (see the garmin adapter's flatten-segments converter) and consumers MUST rely on array order, not on index arithmetic.
poolLength is bounded to [1, 655] meters — generous enough for endless pools (~5 m) and the FIT protocol envelope, while rejecting nonsense values like 0.0001 or 99999. KRD always stores pool length normalized to meters; adapters that accept yard-based pools convert on ingest (see length-unit.converter), so poolLengthUnit is fixed to "meters" here rather than carrying the source unit.