|
| 1 | +import type { DeepPartial } from 'utility-types' |
| 2 | +import type { Id, ResolvableDate, SchemaNodeInput, Thing } from '../../types' |
| 3 | +import { |
| 4 | + IdentityId, |
| 5 | + defineSchemaResolver, |
| 6 | + prefixId, |
| 7 | + resolveId, |
| 8 | +} from '../../utils' |
| 9 | +import type { Organization } from '../Organization' |
| 10 | +import type { PostalAddress } from '../PostalAddress' |
| 11 | +import { defineSchemaOrgComponent } from '../../components/defineSchemaOrgComponent' |
| 12 | +import type { Person } from '../Person' |
| 13 | +import type { Offer } from '../Offer' |
| 14 | +import type { ImageInput } from '../Image' |
| 15 | + |
| 16 | +export interface Place extends Thing { |
| 17 | + '@type': 'Place' |
| 18 | + name: string |
| 19 | + address: PostalAddress |
| 20 | +} |
| 21 | + |
| 22 | +export interface VirtualLocation extends Thing { |
| 23 | + '@type': 'VirtualLocation' |
| 24 | + /** |
| 25 | + * URL of the item. |
| 26 | + */ |
| 27 | + url: string |
| 28 | +} |
| 29 | + |
| 30 | +export interface Event extends Thing { |
| 31 | + /** |
| 32 | + * Description of the event. |
| 33 | + * Describe all details of the event to make it easier for users to understand and attend the event. |
| 34 | + */ |
| 35 | + description?: string |
| 36 | + /** |
| 37 | + * The end date and time of the item (in ISO 8601 date format). |
| 38 | + */ |
| 39 | + endDate?: ResolvableDate |
| 40 | + /** |
| 41 | + * The eventAttendanceMode of an event indicates whether it occurs online, offline, or a mix. |
| 42 | + */ |
| 43 | + eventAttendanceMode?: Id |
| 44 | + /** |
| 45 | + * An eventStatus of an event represents its status; particularly useful when an event is cancelled or rescheduled. |
| 46 | + */ |
| 47 | + eventStatus?: 'EventCancelled' | 'EventMovedOnline' | 'EventPostponed' | 'EventRescheduled' | 'EventScheduled' |
| 48 | + /** |
| 49 | + * Repeated ImageObject or URL |
| 50 | + * |
| 51 | + * URL of an image or logo for the event or tour. |
| 52 | + * Including an image helps users understand and engage with your event. |
| 53 | + * We recommend that images are 1920px wide (the minimum width is 720px). |
| 54 | + */ |
| 55 | + image?: ImageInput |
| 56 | + /** |
| 57 | + * The location of the event. |
| 58 | + * There are different requirements depending on if the event is happening online or at a physical location |
| 59 | + */ |
| 60 | + location?: Place | VirtualLocation |
| 61 | + /** |
| 62 | + * An offer to provide this item—for example, an offer to sell a product, |
| 63 | + * rent the DVD of a movie, perform a service, or give away tickets to an event. |
| 64 | + * Use businessFunction to indicate the kind of transaction offered, i.e. sell, lease, etc. |
| 65 | + * This property can also be used to describe a Demand. |
| 66 | + * While this property is listed as expected on a number of common types, it can be used in others. |
| 67 | + * In that case, using a second type, such as Product or a subtype of Product, can clarify the nature of the offer. |
| 68 | + */ |
| 69 | + offers?: Offer |
| 70 | + /** |
| 71 | + * An organizer of an Event. |
| 72 | + */ |
| 73 | + organizer?: Organization | Person |
| 74 | + /** |
| 75 | + * A performer at the event—for example, a presenter, musician, musical group or actor. |
| 76 | + */ |
| 77 | + performer?: Organization | Person |
| 78 | + /** |
| 79 | + * Used in conjunction with eventStatus for rescheduled or cancelled events. |
| 80 | + * This property contains the previously scheduled start date. |
| 81 | + * For rescheduled events, the startDate property should be used for the newly scheduled start date. |
| 82 | + * In the (rare) case of an event that has been postponed and rescheduled multiple times, this field may be repeated. |
| 83 | + */ |
| 84 | + previousStartDate?: ResolvableDate |
| 85 | + /** |
| 86 | + * The start date and time of the item (in ISO 8601 date format). |
| 87 | + */ |
| 88 | + startDate?: ResolvableDate |
| 89 | +} |
| 90 | + |
| 91 | +export const defineEventPartial = <K>(input?: DeepPartial<Event> & K) => |
| 92 | + // hacky way for users to get around strict typing when using custom schema, route meta or augmentation |
| 93 | + defineEvent(input as Event) |
| 94 | + |
| 95 | +/** |
| 96 | + * An event happening at a certain time and location, such as a concert, lecture, or festival. |
| 97 | + * |
| 98 | + * Ticketing information may be added via the "offers" property. |
| 99 | + * Repeated events may be structured as separate Event objects. |
| 100 | + */ |
| 101 | +export function defineEvent<T extends SchemaNodeInput<Event>>(input: T) { |
| 102 | + return defineSchemaResolver<T, Event>(input, { |
| 103 | + required: [ |
| 104 | + 'location', |
| 105 | + 'startDate', |
| 106 | + ], |
| 107 | + defaults({ canonicalHost }) { |
| 108 | + return { |
| 109 | + '@type': 'Event', |
| 110 | + '@id': prefixId(canonicalHost, IdentityId), |
| 111 | + 'url': canonicalHost, |
| 112 | + } |
| 113 | + }, |
| 114 | + resolve(node, client) { |
| 115 | + resolveId(node, client.canonicalHost) |
| 116 | + return node |
| 117 | + }, |
| 118 | + }) |
| 119 | +} |
| 120 | + |
| 121 | +export const SchemaOrgEvent = defineSchemaOrgComponent('SchemaOrgEvent', defineEvent) |
0 commit comments