mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 16:13:15 +00:00
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
/**
|
|
* Structured mail: read the schema.org markup that airlines, hotels, shops
|
|
* and carriers put into their HTML mail, and turn it into cards. Plain
|
|
* TypeScript; the only DOM dependency is the HTML parser, which a caller
|
|
* without DOMParser (the native app) passes in.
|
|
*
|
|
* const cards = readStructuredMail(html, { mailDate });
|
|
* const shown = needsAirportZones(cards)
|
|
* ? resolveCards(cards, await loadAirportZones())
|
|
* : resolveCards(cards);
|
|
*/
|
|
import { extractStructuredData } from './extract';
|
|
import { mergeCandidates } from './merge';
|
|
import { hasReservation, normalizeItems } from './normalize';
|
|
import type { StructuredCard } from './types';
|
|
import { validateCard } from './validate';
|
|
|
|
export interface ReadOptions {
|
|
/** When the mail was sent (else received): bookings far from it are doubtful. */
|
|
mailDate: Date;
|
|
parseHtml?: (html: string) => Document;
|
|
}
|
|
|
|
export interface DetailedRead {
|
|
/** Validated cards, merged to one per booking, zones not yet resolved. */
|
|
cards: StructuredCard[];
|
|
/**
|
|
* Whether the markup holds any reservation, valid or rejected. Such a mail
|
|
* is read from its markup alone: a pass must not bring back a booking the
|
|
* markup rejected or cancelled, nor add a second card for it.
|
|
*/
|
|
hadBookingMarkup: boolean;
|
|
}
|
|
|
|
/** readStructuredMail, plus whether the markup described a booking at all. */
|
|
export function readStructuredMailDetailed(html: string, options: ReadOptions): DetailedRead {
|
|
const extracted = extractStructuredData(html, options.parseHtml);
|
|
const cards = normalizeItems(extracted);
|
|
return {
|
|
cards: mergeCandidates(cards.map((card) => validateCard(card, options.mailDate))),
|
|
hadBookingMarkup: hasReservation(extracted),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Cards from one HTML body: validated and merged to one card per booking,
|
|
* with zones not yet resolved (resolveCards).
|
|
*/
|
|
export function readStructuredMail(html: string, options: ReadOptions): StructuredCard[] {
|
|
return readStructuredMailDetailed(html, options).cards;
|
|
}
|
|
|
|
export { extractStructuredData, mayContainStructuredData } from './extract';
|
|
export { normalizeItems } from './normalize';
|
|
export { validateCard } from './validate';
|
|
export { mergeCandidates } from './merge';
|
|
export { needsAirportZones, resolveCards } from './resolve';
|
|
export { loadAirportZones } from './time-zones';
|
|
export * from './types';
|