add types and schemas

This commit is contained in:
ItsMalma
2025-11-08 13:51:18 +07:00
parent b347ab0250
commit e6386648be
28 changed files with 1082 additions and 101 deletions

View File

@@ -0,0 +1,29 @@
import z from "zod";
export const airlineRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
code: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(10, "Max 10 characters."),
logo: z.base64("Must be base64 string.").nonempty("Must not empty."),
skytrax_rating: z
.number("Must be number.")
.int("Must be integer.")
.min(1, "Minimum 1.")
.max(5, "Maximum 5."),
skytrax_type: z.enum(
["full_service", "low_cost"],
"Must be either 'full_service' or 'low_cost'.",
),
});
export const airlineQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,21 @@
import type {
airlineQuerySchema,
airlineRequestSchema,
} from "@/modules/airline/airline.schemas";
import z from "zod";
export type AirlineRequest = z.infer<typeof airlineRequestSchema>;
export type AirlineQuery = z.infer<typeof airlineQuerySchema>;
export type AirlineResponse = {
id: string;
slug: string;
name: string;
code: string;
logo: string;
skytrax_rating: number;
skytrax_type: "full_service" | "low_cost";
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,23 @@
import z from "zod";
export const airportRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
code: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(10, "Max 10 characters."),
city_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});
export const airportQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,20 @@
import type {
airportQuerySchema,
airportRequestSchema,
} from "@/modules/airport/airport.schemas";
import type { CityResponse } from "@/modules/city/city.types";
import z from "zod";
export type AirportRequest = z.infer<typeof airportRequestSchema>;
export type AirportQuery = z.infer<typeof airportQuerySchema>;
export type AirportResponse = {
id: string;
slug: string;
name: string;
code: string;
city: CityResponse;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,19 @@
import z from "zod";
export const cityRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
country_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});
export const cityQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,19 @@
import type {
cityQuerySchema,
cityRequestSchema,
} from "@/modules/city/city.schemas";
import type { CountryResponse } from "@/modules/country/country.types";
import z from "zod";
export type CityRequest = z.infer<typeof cityRequestSchema>;
export type CityQuery = z.infer<typeof cityQuerySchema>;
export type CityResponse = {
id: string;
slug: string;
name: string;
country: CountryResponse;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,15 @@
import z from "zod";
export const countryRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
});
export const countryQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,17 @@
import type {
countryQuerySchema,
countryRequestSchema,
} from "@/modules/country/country.schemas";
import z from "zod";
export type CountryRequest = z.infer<typeof countryRequestSchema>;
export type CountryQuery = z.infer<typeof countryQuerySchema>;
export type CountryResponse = {
id: string;
slug: string;
name: string;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,83 @@
import { timeSchema } from "@/common/schemas";
import z from "zod";
export const flightRequestSchema = z.object({
airline_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
number: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
departure_airport_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
departure_terminal: z
.string("Must be string.")
.max(100, "Max 100 characters.")
.nullable(),
departure_gate: z
.string("Must be string.")
.max(100, "Max 100 characters.")
.nullable(),
departure_time: timeSchema,
arrival_airport_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
arrival_terminal: z
.string("Must be string.")
.max(100, "Max 100 characters.")
.nullable(),
arrival_gate: z
.string("Must be string.")
.max(100, "Max 100 characters.")
.nullable(),
duration: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
aircraft: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
});
export const flightClassRequestSchema = z.object({
class: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
seat_layout: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(10, "Max 10 characters."),
baggage: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
cabin_baggage: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
});
export const flightQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(220, "Max 220 characters."),
});
export const flightClassQuerySchema = z.object({
flight_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(220, "Max 220 characters."),
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(420, "Max 420 characters."),
});

View File

@@ -0,0 +1,48 @@
import type { AirlineResponse } from "@/modules/airline/airline.types";
import type { AirportResponse } from "@/modules/airport/airport.types";
import type {
flightClassQuerySchema,
flightClassRequestSchema,
flightQuerySchema,
flightRequestSchema,
} from "@/modules/flight/flight.schemas";
import z from "zod";
export type FlightRequest = z.infer<typeof flightRequestSchema>;
export type FlightClassRequest = z.infer<typeof flightClassRequestSchema>;
export type FlightQuery = z.infer<typeof flightQuerySchema>;
export type FlightClassQuery = z.infer<typeof flightClassQuerySchema>;
export type FlightResponse = {
id: string;
slug: string;
airline: AirlineResponse;
number: number;
departure_airport: AirportResponse;
departure_terminal: string | null;
departure_gate: string | null;
departure_time: string;
arrival_airport: AirportResponse;
arrival_terminal: string | null;
arrival_gate: string | null;
arrival_time: string;
duration: number;
aircraft: string;
created_at: Date;
updated_at: Date;
};
export type FlightClassResponse = {
id: string;
slug: string;
flight: FlightResponse;
class: string;
seat_layout: string;
baggage: number;
cabin_baggage: number;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,96 @@
import z from "zod";
export const hotelFacilityRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
icon: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
});
export const hotelRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
city_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
star: z
.number("Must be number.")
.int("Must be integer.")
.min(1, "Minimum 1.")
.max(7, "Maximum 7."),
images: z
.array(
z.base64("Must be base64 string.").nonempty("Must not empty."),
"Must be array.",
)
.nonempty("Must not empty."),
google_maps_link: z
.url("Must be valid string URL.")
.nonempty("Must not empty.")
.max(500, "Max 500 characters."),
google_maps_embed: z
.url("Must be valid string URL.")
.nonempty("Must not empty.")
.max(500, "Max 500 characters."),
google_reviews_link: z
.url("Must be valid string URL.")
.nonempty("Must not empty.")
.max(500, "Max 500 characters."),
description: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(1000, "Max 1000 characters."),
facility_slugs: z
.array(
z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
"Must be array.",
)
.nonempty("Must not empty."),
address: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
landmark: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
distance_to_landmark: z
.number("Must be number.")
.positive("Must be positive."),
food_type: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
food_amount: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
food_menu: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
});
export const hotelFacilityQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});
export const hotelQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,45 @@
import type { CityResponse } from "@/modules/city/city.types";
import type {
hotelFacilityRequestSchema,
hotelQuerySchema,
hotelRequestSchema,
} from "@/modules/hotel/hotel.schemas";
import z from "zod";
export type HotelFacilityRequest = z.infer<typeof hotelFacilityRequestSchema>;
export type HotelRequest = z.infer<typeof hotelRequestSchema>;
export type HotelFacilityQuery = z.infer<typeof hotelFacilityRequestSchema>;
export type HotelQuery = z.infer<typeof hotelQuerySchema>;
export type HotelFacilityResponse = {
id: string;
slug: string;
name: string;
icon: string;
created_at: Date;
updated_at: Date;
};
export type HotelResponse = {
id: string;
slug: string;
name: string;
city: CityResponse;
star: number;
google_maps_link: string;
google_maps_embed: string;
google_reviews_link: string;
description: string;
facilities: HotelFacilityResponse[];
address: string;
landmark: string;
distance_to_landmark: number;
food_type: string;
food_amount: number;
food_menu: string;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,122 @@
import { dateSchema, timeSchema } from "@/common/schemas";
import z from "zod";
export const packageRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
type: z.enum(["reguler", "plus"], "Must be either 'reguler' or 'plus'."),
class: z.enum(
["silver", "gold", "platinum"],
"Must be either 'silver', 'gold', or 'platinum'.",
),
thumbnail: z.base64("Must be base64 string.").nonempty("Must not empty."),
use_fast_train: z.boolean("Must be boolean."),
});
export const packageDetailRequestSchema = z.object({
departure_date: dateSchema,
tour_flight_slugs: z
.array(
z
.string("Must be string.")
.nonempty("Must not empty.")
.max(420, "Max 420 characters."),
"Must be array.",
)
.nonempty("Must not empty."),
outbound_flight_slugs: z
.array(
z
.string("Must be string.")
.nonempty("Must not empty.")
.max(420, "Max 420 characters."),
"Must be array.",
)
.nonempty("Must not empty."),
inbound_flight_slugs: z
.array(
z
.string("Must be string.")
.nonempty("Must not empty.")
.max(420, "Max 420 characters."),
"Must be array.",
)
.nonempty("Must not empty."),
tour_hotels: z.array(
z.object(
{
hotel_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
"Must be array.",
),
makkah_hotel: z.object(
{
hotel_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
madinah_hotel: z.object(
{
hotel_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
transportation_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
quad_price: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
triple_price: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
double_price: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
infant_price: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive.")
.nullable(),
});
export const packageQuerySchema = z.object({
detail_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});
export const packageDetailQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});

View File

@@ -0,0 +1,56 @@
import type { FlightClassResponse } from "@/modules/flight/flight.types";
import type { HotelResponse } from "@/modules/hotel/hotel.types";
import type {
packageDetailQuerySchema,
packageDetailRequestSchema,
packageQuerySchema,
packageRequestSchema,
} from "@/modules/package/package.schemas";
import type { TransportationClassResponse } from "@/modules/transportation/transportation.types";
import z from "zod";
export type PackageRequest = z.infer<typeof packageRequestSchema>;
export type PackageDetailRequest = z.infer<typeof packageDetailRequestSchema>;
export type PackageQuery = z.infer<typeof packageQuerySchema>;
export type PackageDetailQuery = z.infer<typeof packageDetailQuerySchema>;
export type PackageResponse = {
id: string;
slug: string;
name: string;
type: "reguler" | "plus";
class: "silver" | "gold" | "platinum";
thumbnail: string;
use_fast_train: boolean;
created_at: Date;
updated_at: Date;
};
export type PackageHotelResponse = {
hotel: HotelResponse;
check_in: string;
check_out: string;
};
export type PackageDetailResponse = {
id: string;
slug: string;
package: PackageResponse;
departure_date: string;
tour_flights: FlightClassResponse[];
outbound_flights: FlightClassResponse[];
inbound_flights: FlightClassResponse[];
tour_hotels: PackageHotelResponse[];
makkah_hotel: PackageHotelResponse;
medina_hotel: PackageHotelResponse;
transportation: TransportationClassResponse;
quad_price: number;
triple_price: number;
double_price: number;
infant_price: number | null;
created_at: Date;
updated_at: Date;
};

View File

@@ -0,0 +1,47 @@
import z from "zod";
export const transportationRequestSchema = z.object({
name: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
type: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
});
export const transportationClassRequestSchema = z.object({
class: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(100, "Max 100 characters."),
total_seats: z
.number("Must be number.")
.int("Must be integer.")
.positive("Must be positive."),
images: z
.array(
z.base64("Must be base64 string.").nonempty("Must not empty."),
"Must be array.",
)
.nonempty("Must not empty."),
});
export const transportationQuerySchema = z.object({
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
});
export const transportationClassQuerySchema = z.object({
transportation_slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(200, "Max 200 characters."),
slug: z
.string("Must be string.")
.nonempty("Must not empty.")
.max(400, "Max 400 characters."),
});

View File

@@ -0,0 +1,38 @@
import type {
transportationClassQuerySchema,
transportationClassRequestSchema,
transportationQuerySchema,
transportationRequestSchema,
} from "@/modules/transportation/transportation.schemas";
import z from "zod";
export type TransportationRequest = z.infer<typeof transportationRequestSchema>;
export type TransportationClassRequest = z.infer<
typeof transportationClassRequestSchema
>;
export type TransportationQuery = z.infer<typeof transportationQuerySchema>;
export type TransportationClassQuery = z.infer<
typeof transportationClassQuerySchema
>;
export type TransportationResponse = {
id: string;
slug: string;
name: string;
created_at: Date;
updated_at: Date;
};
export type TransportationClassResponse = {
id: string;
slug: string;
transportation: TransportationResponse;
class: string;
total_seats: number;
images: string[];
created_at: Date;
updated_at: Date;
};