mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-30 16:16:19 +00:00
177 lines
4.4 KiB
TypeScript
177 lines
4.4 KiB
TypeScript
/**
|
|
* The model booking, shipping and order mail is read into. Plain data, no
|
|
* React and no app imports, so the native app can reuse the parser.
|
|
*/
|
|
|
|
export type BookingKind = 'flight' | 'train' | 'bus' | 'lodging' | 'rentalcar' | 'event' | 'restaurant';
|
|
export type TransportKind = 'flight' | 'train' | 'bus';
|
|
export type ReservationStatus = 'confirmed' | 'pending' | 'hold' | 'cancelled';
|
|
export type OrderStatus =
|
|
| 'payment_due' | 'processing' | 'problem' | 'in_transit'
|
|
| 'pickup_available' | 'returned' | 'delivered' | 'cancelled';
|
|
|
|
/** A time as the mail wrote it, local to the place it belongs to. */
|
|
export interface Moment {
|
|
/** YYYY-MM-DD, local. */
|
|
date: string;
|
|
/** HH:mm:ss, local; absent for a date-only value. */
|
|
time?: string;
|
|
/** Minutes east of UTC, from the value; absent when the mail gave none. */
|
|
offsetMinutes?: number;
|
|
/** ISO instant; set when the time and its zone or offset are known. */
|
|
utc?: string;
|
|
/**
|
|
* IANA zone after resolution (resolveCards): airport, country or a
|
|
* fixed-offset zone; null for a time that stays floating. Absent before.
|
|
*/
|
|
zone?: string | null;
|
|
}
|
|
|
|
export interface Address {
|
|
street?: string;
|
|
locality?: string;
|
|
region?: string;
|
|
postalCode?: string;
|
|
/** ISO 3166-1 alpha-2, when the mail gave one. */
|
|
country?: string;
|
|
/** Country as the mail named it, when that wasn't a code. */
|
|
countryName?: string;
|
|
}
|
|
|
|
export interface Place {
|
|
name?: string;
|
|
/** IATA airport code for airports, upper case. */
|
|
code?: string;
|
|
address?: Address;
|
|
}
|
|
|
|
/** A link a card may show: http(s) only, host shown next to it. */
|
|
export interface Link {
|
|
url: string;
|
|
host: string;
|
|
}
|
|
|
|
export interface Seat {
|
|
passenger?: string;
|
|
seat: string;
|
|
}
|
|
|
|
export interface TransportLeg {
|
|
carrier?: string;
|
|
/** IATA airline code for flights. */
|
|
carrierCode?: string;
|
|
number?: string;
|
|
departure: { place: Place; at: Moment };
|
|
arrival?: { place: Place; at?: Moment };
|
|
seats: Seat[];
|
|
status?: ReservationStatus;
|
|
}
|
|
|
|
export interface BookingLinks {
|
|
checkin?: Link;
|
|
manage?: Link;
|
|
ticket?: Link;
|
|
}
|
|
|
|
export type CardSource = 'json-ld' | 'microdata' | 'pkpass';
|
|
|
|
interface BookingBase {
|
|
/** Merge key: equal keys are the same booking. */
|
|
key: string;
|
|
kind: BookingKind;
|
|
reference?: string;
|
|
status?: ReservationStatus;
|
|
passengers: string[];
|
|
provider?: string;
|
|
links: BookingLinks;
|
|
modified?: string;
|
|
source: CardSource;
|
|
}
|
|
|
|
export interface TransportBooking extends BookingBase {
|
|
kind: TransportKind;
|
|
legs: TransportLeg[];
|
|
}
|
|
|
|
export interface LodgingBooking extends BookingBase {
|
|
kind: 'lodging';
|
|
name: string;
|
|
address?: Address;
|
|
phone?: string;
|
|
checkin: Moment;
|
|
checkout: Moment;
|
|
}
|
|
|
|
export interface RentalCarBooking extends BookingBase {
|
|
kind: 'rentalcar';
|
|
company?: string;
|
|
car?: string;
|
|
pickup: { place: Place; at: Moment };
|
|
dropoff: { place: Place; at: Moment };
|
|
}
|
|
|
|
export interface EventBooking extends BookingBase {
|
|
kind: 'event';
|
|
name: string;
|
|
venue?: Place;
|
|
start: Moment;
|
|
end?: Moment;
|
|
tickets: string[];
|
|
}
|
|
|
|
export interface RestaurantBooking extends BookingBase {
|
|
kind: 'restaurant';
|
|
name: string;
|
|
address?: Address;
|
|
start: Moment;
|
|
partySize?: number;
|
|
}
|
|
|
|
export type Booking = TransportBooking | LodgingBooking | RentalCarBooking | EventBooking | RestaurantBooking;
|
|
|
|
export interface Item {
|
|
name: string;
|
|
quantity?: number;
|
|
/** Remote image; a card shows it only when remote content may load. */
|
|
image?: Link;
|
|
}
|
|
|
|
export interface Parcel {
|
|
carrier?: string;
|
|
trackingNumber?: string;
|
|
trackingUrl?: Link;
|
|
expectedBy?: Moment;
|
|
items: Item[];
|
|
}
|
|
|
|
/** An Order and/or the ParcelDeliveries for one order number. */
|
|
export interface Shipment {
|
|
kind: 'shipment';
|
|
key: string;
|
|
merchant?: string;
|
|
orderNumber?: string;
|
|
status?: OrderStatus;
|
|
items: Item[];
|
|
/** Amount normalised to a dot decimal ("399.00"). */
|
|
total?: { amount: string; currency: string };
|
|
orderUrl?: Link;
|
|
parcels: Parcel[];
|
|
source: CardSource;
|
|
}
|
|
|
|
export type StructuredCard = Booking | Shipment;
|
|
|
|
/** A card plus the reasons validation found to doubt it (empty = fine). */
|
|
export interface Candidate {
|
|
card: StructuredCard;
|
|
problems: string[];
|
|
}
|
|
|
|
export function isBooking(card: StructuredCard): card is Booking {
|
|
return card.kind !== 'shipment';
|
|
}
|
|
|
|
export function isTransport(card: StructuredCard): card is TransportBooking {
|
|
return card.kind === 'flight' || card.kind === 'train' || card.kind === 'bus';
|
|
}
|