schemaorg-kit 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1991 @@
1
+ // src/core/base.ts
2
+ import { z } from "zod";
3
+ var SchemaNode = class {
4
+ constructor(schema2, data) {
5
+ this.schema = schema2;
6
+ this.data = data;
7
+ }
8
+ /** Returns the raw validated object */
9
+ toObject() {
10
+ return this.data;
11
+ }
12
+ /** Returns a JSON-LD ready object with @context */
13
+ toJsonLd() {
14
+ return {
15
+ "@context": "https://schema.org",
16
+ ...this.data
17
+ };
18
+ }
19
+ /** Returns a <script type="application/ld+json"> tag string */
20
+ toScript() {
21
+ return `<script type="application/ld+json">
22
+ ${JSON.stringify(this.toJsonLd(), null, 2)}
23
+ </script>`;
24
+ }
25
+ /** Returns prettified JSON string */
26
+ toString() {
27
+ return JSON.stringify(this.toJsonLd(), null, 2);
28
+ }
29
+ /** Validates and throws if invalid — useful in CI/build steps */
30
+ validate() {
31
+ this.schema.parse(this.data);
32
+ return this;
33
+ }
34
+ /** Safe validation — returns errors without throwing */
35
+ safeParse() {
36
+ return this.schema.safeParse(this.data);
37
+ }
38
+ };
39
+ function makeFactory(schema2) {
40
+ return (data) => {
41
+ const parsed = schema2.parse(data);
42
+ return new SchemaNode(schema2, parsed);
43
+ };
44
+ }
45
+
46
+ // src/types/things/Person.ts
47
+ import { z as z5 } from "zod";
48
+
49
+ // src/types/things/Thing.ts
50
+ import { z as z4 } from "zod";
51
+
52
+ // src/types/shared/ImageObject.ts
53
+ import { z as z3 } from "zod";
54
+
55
+ // src/types/shared/PersonOrOrgRef.ts
56
+ import { z as z2 } from "zod";
57
+ var PersonOrOrgRef = z2.union([
58
+ z2.string(),
59
+ // Accept any Person or Organization object — including full schema outputs via .toObject().
60
+ // .catchall() allows extra fields; name/url are optional to match ThingSchema's base types.
61
+ z2.object({ "@type": z2.literal("Person") }).catchall(z2.unknown()),
62
+ z2.object({ "@type": z2.literal("Organization") }).catchall(z2.unknown())
63
+ ]);
64
+
65
+ // src/types/shared/ImageObject.ts
66
+ var ImageObjectSchema = z3.object({
67
+ "@type": z3.literal("ImageObject").default("ImageObject"),
68
+ url: z3.url(),
69
+ contentUrl: z3.url().optional(),
70
+ width: z3.union([
71
+ z3.number(),
72
+ z3.object({ "@type": z3.literal("QuantitativeValue"), value: z3.number(), unitCode: z3.string().optional() })
73
+ ]).optional(),
74
+ height: z3.union([
75
+ z3.number(),
76
+ z3.object({ "@type": z3.literal("QuantitativeValue"), value: z3.number(), unitCode: z3.string().optional() })
77
+ ]).optional(),
78
+ caption: z3.string().optional(),
79
+ description: z3.string().optional(),
80
+ name: z3.string().optional(),
81
+ // Google image metadata requirements:
82
+ creator: PersonOrOrgRef.optional(),
83
+ creditText: z3.string().optional(),
84
+ copyrightNotice: z3.string().optional(),
85
+ license: z3.url().optional(),
86
+ acquireLicensePage: z3.url().optional(),
87
+ representativeOfPage: z3.boolean().optional(),
88
+ encodingFormat: z3.string().optional(),
89
+ // MIME type, e.g. "image/jpeg"
90
+ uploadDate: z3.string().optional(),
91
+ thumbnailUrl: z3.url().optional(),
92
+ embedUrl: z3.url().optional()
93
+ });
94
+ var ImageOrUrl = z3.union([z3.url(), ImageObjectSchema]);
95
+ var createImageObject = makeFactory(ImageObjectSchema);
96
+
97
+ // src/types/things/Thing.ts
98
+ var AnyThingRef = z4.lazy(
99
+ () => z4.object({ "@type": z4.string() }).catchall(z4.unknown())
100
+ );
101
+ var ThingSchema = z4.object({
102
+ "@type": z4.string(),
103
+ // JSON-LD node identifier — useful for @graph cross-references
104
+ "@id": z4.string().optional(),
105
+ // Core identity
106
+ name: z4.string().optional(),
107
+ description: z4.string().optional(),
108
+ url: z4.url().optional(),
109
+ identifier: z4.union([z4.string(), z4.number()]).optional(),
110
+ // Media — single image or array (Google recommends multiple aspect ratios)
111
+ image: z4.union([ImageOrUrl, z4.array(ImageOrUrl)]).optional(),
112
+ // Discovery
113
+ sameAs: z4.union([z4.url(), z4.array(z4.url())]).optional(),
114
+ alternateName: z4.string().optional(),
115
+ // Relationships (loose refs to avoid circular type inference)
116
+ subjectOf: AnyThingRef.optional(),
117
+ mainEntityOfPage: z4.union([z4.url(), AnyThingRef]).optional()
118
+ });
119
+ function extendThing(type, shape) {
120
+ return ThingSchema.extend({
121
+ "@type": z4.literal(type).default(type),
122
+ ...shape
123
+ });
124
+ }
125
+
126
+ // src/types/things/Person.ts
127
+ var PersonSchema = extendThing("Person", {
128
+ givenName: z5.string().optional(),
129
+ familyName: z5.string().optional(),
130
+ email: z5.string().email().optional(),
131
+ telephone: z5.string().optional(),
132
+ jobTitle: z5.string().optional(),
133
+ worksFor: z5.lazy(() => z5.object({ "@type": z5.string(), name: z5.string() })).optional(),
134
+ birthDate: z5.string().optional(),
135
+ // ISO 8601
136
+ gender: z5.enum(["Male", "Female", "Unknown"]).optional(),
137
+ nationality: z5.string().optional(),
138
+ address: z5.object({
139
+ "@type": z5.literal("PostalAddress"),
140
+ streetAddress: z5.string().optional(),
141
+ addressLocality: z5.string().optional(),
142
+ addressRegion: z5.string().optional(),
143
+ postalCode: z5.string().optional(),
144
+ addressCountry: z5.string().optional()
145
+ }).optional()
146
+ });
147
+ var createPerson = makeFactory(PersonSchema);
148
+
149
+ // src/types/things/Organization.ts
150
+ import { z as z11 } from "zod";
151
+
152
+ // src/types/shared/PostalAddress.ts
153
+ import { z as z6 } from "zod";
154
+ var PostalAddressSchema = z6.object({
155
+ "@type": z6.literal("PostalAddress").default("PostalAddress"),
156
+ streetAddress: z6.string().optional(),
157
+ addressLocality: z6.string().optional(),
158
+ // city
159
+ addressRegion: z6.string().optional(),
160
+ // state/province
161
+ postalCode: z6.string().optional(),
162
+ addressCountry: z6.string().optional(),
163
+ // ISO 3166-1 alpha-2, e.g. "US"
164
+ postOfficeBoxNumber: z6.string().optional()
165
+ });
166
+
167
+ // src/types/shared/ContactPoint.ts
168
+ import { z as z7 } from "zod";
169
+ var ContactPointSchema = z7.object({
170
+ "@type": z7.literal("ContactPoint").default("ContactPoint"),
171
+ telephone: z7.string().optional(),
172
+ contactType: z7.string().optional(),
173
+ // e.g. "customer support", "sales"
174
+ email: z7.string().email().optional(),
175
+ areaServed: z7.union([z7.string(), z7.array(z7.string())]).optional(),
176
+ availableLanguage: z7.union([z7.string(), z7.array(z7.string())]).optional(),
177
+ hoursAvailable: z7.string().optional(),
178
+ contactOption: z7.string().optional()
179
+ // e.g. "TollFree", "HearingImpairedSupported"
180
+ });
181
+
182
+ // src/types/shared/Offer.ts
183
+ import { z as z10 } from "zod";
184
+
185
+ // src/types/shared/ShippingDetails.ts
186
+ import { z as z9 } from "zod";
187
+
188
+ // src/types/shared/OpeningHoursSpecification.ts
189
+ import { z as z8 } from "zod";
190
+ var DayOfWeek = z8.enum([
191
+ "Monday",
192
+ "Tuesday",
193
+ "Wednesday",
194
+ "Thursday",
195
+ "Friday",
196
+ "Saturday",
197
+ "Sunday"
198
+ ]);
199
+ var OpeningHoursSpecificationSchema = z8.object({
200
+ "@type": z8.literal("OpeningHoursSpecification").default("OpeningHoursSpecification"),
201
+ dayOfWeek: z8.union([DayOfWeek, z8.array(DayOfWeek)]),
202
+ opens: z8.string().optional(),
203
+ // "HH:MM:SS" e.g. "09:00:00"
204
+ closes: z8.string().optional(),
205
+ // "HH:MM:SS" e.g. "17:00:00"
206
+ validFrom: z8.string().optional(),
207
+ // ISO 8601 date — for seasonal hours
208
+ validThrough: z8.string().optional()
209
+ // ISO 8601 date
210
+ });
211
+
212
+ // src/types/shared/ShippingDetails.ts
213
+ var DefinedRegionSchema = z9.object({
214
+ "@type": z9.literal("DefinedRegion").default("DefinedRegion"),
215
+ name: z9.string().optional(),
216
+ /** ISO 3166-1 alpha-2 country code, e.g. "US", "GB" */
217
+ addressCountry: z9.string().optional(),
218
+ /** State/province code(s) */
219
+ addressRegion: z9.union([z9.string(), z9.array(z9.string())]).optional(),
220
+ /** Postal code prefix(es) */
221
+ postalCodePrefix: z9.union([z9.string(), z9.array(z9.string())]).optional(),
222
+ /** Postal code range */
223
+ postalCodeRange: z9.object({
224
+ postalCodeBegin: z9.string(),
225
+ postalCodeEnd: z9.string()
226
+ }).optional()
227
+ });
228
+ var QuantitativeDaysSchema = z9.object({
229
+ "@type": z9.literal("QuantitativeValue").default("QuantitativeValue"),
230
+ minValue: z9.number().int().nonnegative().optional(),
231
+ maxValue: z9.number().int().nonnegative().optional(),
232
+ /** Unit code — always "DAY" for delivery times */
233
+ unitCode: z9.string().default("DAY")
234
+ });
235
+ var ShippingDeliveryTimeSchema = z9.object({
236
+ "@type": z9.literal("ShippingDeliveryTime").default("ShippingDeliveryTime"),
237
+ /** Days the warehouse processes orders (e.g. Mon–Fri) */
238
+ businessDays: z9.object({
239
+ "@type": z9.literal("OpeningHoursSpecification").default("OpeningHoursSpecification"),
240
+ dayOfWeek: z9.union([DayOfWeek, z9.array(DayOfWeek)])
241
+ }).optional(),
242
+ /** Order processing/packing time in days */
243
+ handlingTime: QuantitativeDaysSchema.optional(),
244
+ /** Transit time in days after dispatch */
245
+ transitTime: QuantitativeDaysSchema.optional(),
246
+ /** Cutoff time for same-day processing, ISO 8601 time, e.g. "14:00:00" */
247
+ cutoffTime: z9.string().optional()
248
+ });
249
+ var OfferShippingDetailsSchema = z9.object({
250
+ "@type": z9.literal("OfferShippingDetails").default("OfferShippingDetails"),
251
+ /** Shipping cost as a MonetaryAmount (use value: 0 for free shipping) */
252
+ shippingRate: z9.object({
253
+ "@type": z9.literal("MonetaryAmount").default("MonetaryAmount"),
254
+ value: z9.number(),
255
+ currency: z9.string()
256
+ }).optional(),
257
+ /** Region(s) this shipping option applies to */
258
+ shippingDestination: z9.union([
259
+ DefinedRegionSchema,
260
+ z9.array(DefinedRegionSchema)
261
+ ]).optional(),
262
+ /** Expected delivery time */
263
+ deliveryTime: ShippingDeliveryTimeSchema.optional(),
264
+ /** Set to true to indicate item cannot be shipped to a destination */
265
+ doesNotShip: z9.boolean().optional(),
266
+ /** Human-readable shipping label, e.g. "Free Shipping", "Express Delivery" */
267
+ shippingLabel: z9.string().optional()
268
+ });
269
+
270
+ // src/types/shared/Offer.ts
271
+ var ItemAvailability = z10.enum([
272
+ "InStock",
273
+ "OutOfStock",
274
+ "PreOrder",
275
+ "Discontinued",
276
+ "LimitedAvailability",
277
+ "SoldOut",
278
+ "OnlineOnly",
279
+ "InStoreOnly",
280
+ "BackOrder"
281
+ ]).transform((v) => `https://schema.org/${v}`);
282
+ var OfferSchema = z10.object({
283
+ "@type": z10.literal("Offer").default("Offer"),
284
+ price: z10.union([z10.number(), z10.string()]),
285
+ priceCurrency: z10.string().length(3),
286
+ // ISO 4217, e.g. "USD"
287
+ availability: ItemAvailability.optional(),
288
+ validFrom: z10.string().optional(),
289
+ // ISO 8601
290
+ validThrough: z10.string().optional(),
291
+ // ISO 8601
292
+ url: z10.url().optional(),
293
+ seller: z10.object({ "@type": z10.string(), name: z10.string() }).optional(),
294
+ category: z10.string().optional(),
295
+ inventoryLevel: z10.object({
296
+ "@type": z10.literal("QuantitativeValue").default("QuantitativeValue"),
297
+ value: z10.number()
298
+ }).optional(),
299
+ priceValidUntil: z10.string().optional(),
300
+ // ISO 8601 date — Google Product requirement
301
+ shippingDetails: z10.union([
302
+ OfferShippingDetailsSchema,
303
+ z10.array(OfferShippingDetailsSchema)
304
+ ]).optional(),
305
+ hasMerchantReturnPolicy: z10.lazy(
306
+ () => z10.object({ "@type": z10.string() }).catchall(z10.unknown())
307
+ ).optional()
308
+ });
309
+ var MerchantReturnPolicySchema = z10.object({
310
+ "@type": z10.literal("MerchantReturnPolicy").default("MerchantReturnPolicy"),
311
+ applicableCountry: z10.union([z10.string(), z10.array(z10.string())]).optional(),
312
+ returnPolicyCategory: z10.string().optional(),
313
+ // schema.org enum URL
314
+ merchantReturnDays: z10.number().int().nonnegative().optional(),
315
+ returnMethod: z10.string().optional(),
316
+ // schema.org enum URL
317
+ returnFees: z10.string().optional(),
318
+ // schema.org enum URL
319
+ refundType: z10.string().optional()
320
+ // schema.org enum URL
321
+ });
322
+ var createOffer = makeFactory(OfferSchema);
323
+ var AggregateOfferSchema = z10.object({
324
+ "@type": z10.literal("AggregateOffer").default("AggregateOffer"),
325
+ lowPrice: z10.number().optional(),
326
+ highPrice: z10.number().optional(),
327
+ priceCurrency: z10.string().length(3).optional(),
328
+ // ISO 4217
329
+ offerCount: z10.number().int().nonnegative().optional(),
330
+ offers: z10.union([OfferSchema, z10.array(OfferSchema)]).optional(),
331
+ availability: ItemAvailability.optional(),
332
+ url: z10.url().optional()
333
+ });
334
+
335
+ // src/types/things/Organization.ts
336
+ var NestedOrgRef = z11.lazy(
337
+ () => z11.object({ "@type": z11.string(), name: z11.string().optional() }).catchall(z11.unknown())
338
+ );
339
+ var OrganizationSchema = extendThing("Organization", {
340
+ legalName: z11.string().optional(),
341
+ email: z11.email().optional(),
342
+ telephone: z11.string().optional(),
343
+ logo: ImageOrUrl.optional(),
344
+ foundingDate: z11.string().optional(),
345
+ // ISO 8601 date
346
+ numberOfEmployees: z11.object({
347
+ "@type": z11.literal("QuantitativeValue").default("QuantitativeValue"),
348
+ value: z11.number()
349
+ }).optional(),
350
+ address: z11.union([z11.string(), PostalAddressSchema]).optional(),
351
+ contactPoint: z11.union([ContactPointSchema, z11.array(ContactPointSchema)]).optional(),
352
+ // Google Organization requirements:
353
+ vatID: z11.string().optional(),
354
+ iso6523Code: z11.string().optional(),
355
+ // e.g. "0060:123456789" (DUNS)
356
+ taxID: z11.string().optional(),
357
+ leiCode: z11.string().optional(),
358
+ duns: z11.string().optional(),
359
+ // Merchant-related (Google seller identity signals):
360
+ hasMerchantReturnPolicy: MerchantReturnPolicySchema.optional(),
361
+ hasShippingService: z11.lazy(
362
+ () => z11.object({ "@type": z11.string() }).catchall(z11.unknown())
363
+ ).optional(),
364
+ // Hierarchical organization (loose refs to avoid circular type inference):
365
+ subOrganization: NestedOrgRef.optional(),
366
+ parentOrganization: NestedOrgRef.optional(),
367
+ sameAs: z11.union([z11.url(), z11.array(z11.url())]).optional()
368
+ });
369
+ var createOrganization = makeFactory(OrganizationSchema);
370
+ var createNGO = makeFactory(
371
+ OrganizationSchema.extend({ "@type": z11.literal("NGO").default("NGO") })
372
+ );
373
+ var createCorporation = makeFactory(
374
+ OrganizationSchema.extend({ "@type": z11.literal("Corporation").default("Corporation") })
375
+ );
376
+ var createOnlineStore = makeFactory(
377
+ OrganizationSchema.extend({ "@type": z11.literal("OnlineStore").default("OnlineStore") })
378
+ );
379
+ var createOnlineBusiness = makeFactory(
380
+ OrganizationSchema.extend({ "@type": z11.literal("OnlineBusiness").default("OnlineBusiness") })
381
+ );
382
+
383
+ // src/types/things/Product.ts
384
+ import { z as z13 } from "zod";
385
+
386
+ // src/types/shared/Rating.ts
387
+ import { z as z12 } from "zod";
388
+ var RatingSchema = z12.object({
389
+ "@type": z12.literal("Rating").default("Rating"),
390
+ ratingValue: z12.union([z12.number(), z12.string()]),
391
+ bestRating: z12.union([z12.number(), z12.string()]).default(5),
392
+ worstRating: z12.union([z12.number(), z12.string()]).default(1),
393
+ ratingExplanation: z12.string().optional(),
394
+ reviewAspect: z12.string().optional()
395
+ });
396
+ var AggregateRatingSchema = z12.object({
397
+ "@type": z12.literal("AggregateRating").default("AggregateRating"),
398
+ ratingValue: z12.union([z12.number(), z12.string()]),
399
+ reviewCount: z12.number().int().nonnegative().optional(),
400
+ ratingCount: z12.number().int().nonnegative().optional(),
401
+ bestRating: z12.union([z12.number(), z12.string()]).default(5),
402
+ worstRating: z12.union([z12.number(), z12.string()]).default(1)
403
+ });
404
+ var ReviewSchema = z12.object({
405
+ "@type": z12.literal("Review").default("Review"),
406
+ reviewBody: z12.string().optional(),
407
+ reviewRating: RatingSchema.optional(),
408
+ author: PersonOrOrgRef,
409
+ datePublished: z12.string().optional(),
410
+ // ISO 8601 date
411
+ publisher: PersonOrOrgRef.optional(),
412
+ // itemReviewed: any Thing — kept loose to avoid circular imports
413
+ itemReviewed: z12.lazy(
414
+ () => z12.object({ "@type": z12.string() }).passthrough()
415
+ ).optional(),
416
+ name: z12.string().optional(),
417
+ // Review headline
418
+ url: z12.string().url().optional()
419
+ });
420
+ var EmployerAggregateRatingSchema = AggregateRatingSchema.extend({
421
+ "@type": z12.literal("EmployerAggregateRating").default("EmployerAggregateRating"),
422
+ itemReviewed: z12.lazy(
423
+ () => z12.object({ "@type": z12.string(), name: z12.string() }).passthrough()
424
+ ).optional()
425
+ });
426
+
427
+ // src/types/things/Product.ts
428
+ var CertificationSchema = z13.object({
429
+ "@type": z13.literal("Certification").default("Certification"),
430
+ name: z13.string(),
431
+ url: z13.url().optional(),
432
+ issuedBy: z13.object({
433
+ "@type": z13.literal("Organization").default("Organization"),
434
+ name: z13.string(),
435
+ url: z13.url().optional()
436
+ }).optional(),
437
+ certificationRatingValue: z13.string().optional(),
438
+ certificationStatus: z13.string().optional(),
439
+ validFrom: z13.string().optional(),
440
+ validThrough: z13.string().optional()
441
+ });
442
+ var ThreeDModelSchema = z13.object({
443
+ "@type": z13.literal("3DModel").default("3DModel"),
444
+ contentUrl: z13.url(),
445
+ /** MIME type, e.g. "model/gltf-binary", "model/gltf+json" */
446
+ encodingFormat: z13.string().optional(),
447
+ name: z13.string().optional()
448
+ });
449
+ var LooseProductRef = z13.lazy(
450
+ () => z13.object({ "@type": z13.string() }).catchall(z13.unknown())
451
+ );
452
+ var LooseProductGroupRef = z13.lazy(
453
+ () => z13.object({ "@type": z13.string() }).catchall(z13.unknown())
454
+ );
455
+ var ProductSchema = extendThing("Product", {
456
+ sku: z13.string().optional(),
457
+ // GTIN identifiers (Google Product requirement):
458
+ gtin: z13.string().optional(),
459
+ gtin8: z13.string().optional(),
460
+ gtin12: z13.string().optional(),
461
+ gtin13: z13.string().optional(),
462
+ gtin14: z13.string().optional(),
463
+ mpn: z13.string().optional(),
464
+ // Manufacturer Part Number
465
+ brand: z13.union([
466
+ z13.string(),
467
+ z13.object({
468
+ "@type": z13.union([z13.literal("Brand"), z13.literal("Organization")]),
469
+ name: z13.string()
470
+ })
471
+ ]).optional(),
472
+ offers: z13.union([
473
+ OfferSchema,
474
+ AggregateOfferSchema,
475
+ z13.array(z13.union([OfferSchema, AggregateOfferSchema]))
476
+ ]).optional(),
477
+ aggregateRating: AggregateRatingSchema.optional(),
478
+ review: z13.union([ReviewSchema, z13.array(ReviewSchema)]).optional(),
479
+ category: z13.string().optional(),
480
+ color: z13.string().optional(),
481
+ material: z13.string().optional(),
482
+ weight: z13.object({
483
+ "@type": z13.literal("QuantitativeValue").default("QuantitativeValue"),
484
+ value: z13.number(),
485
+ unitCode: z13.string()
486
+ }).optional(),
487
+ image: z13.union([ImageOrUrl, z13.array(ImageOrUrl)]).optional(),
488
+ hasMerchantReturnPolicy: MerchantReturnPolicySchema.optional(),
489
+ isVariantOf: LooseProductGroupRef.optional(),
490
+ /** Certifications (CE, Energy Star, Fair Trade, etc.) */
491
+ hasCertification: z13.union([CertificationSchema, z13.array(CertificationSchema)]).optional(),
492
+ /** 3D models for interactive product views in Google Search/Images */
493
+ subjectOf: z13.union([ThreeDModelSchema, z13.array(ThreeDModelSchema)]).optional()
494
+ });
495
+ var ProductGroupSchema = extendThing("ProductGroup", {
496
+ variesBy: z13.union([z13.string(), z13.array(z13.string())]).optional(),
497
+ hasVariant: z13.array(LooseProductRef).optional(),
498
+ productGroupID: z13.string().optional(),
499
+ sku: z13.string().optional(),
500
+ gtin: z13.string().optional(),
501
+ brand: z13.union([
502
+ z13.string(),
503
+ z13.object({
504
+ "@type": z13.union([z13.literal("Brand"), z13.literal("Organization")]),
505
+ name: z13.string()
506
+ })
507
+ ]).optional(),
508
+ offers: z13.union([OfferSchema, z13.array(OfferSchema)]).optional(),
509
+ aggregateRating: AggregateRatingSchema.optional(),
510
+ image: z13.union([ImageOrUrl, z13.array(ImageOrUrl)]).optional()
511
+ });
512
+ var createProduct = makeFactory(ProductSchema);
513
+ var createProductGroup = makeFactory(ProductGroupSchema);
514
+
515
+ // src/types/things/Event.ts
516
+ import { z as z15 } from "zod";
517
+
518
+ // src/types/shared/VideoObject.ts
519
+ import { z as z14 } from "zod";
520
+ var ClipSchema = z14.object({
521
+ "@type": z14.literal("Clip").default("Clip"),
522
+ name: z14.string(),
523
+ startOffset: z14.number(),
524
+ // seconds from start
525
+ endOffset: z14.number().optional(),
526
+ // seconds from start
527
+ url: z14.url().optional()
528
+ // URL pointing to this clip
529
+ });
530
+ var BroadcastEventSchema = z14.object({
531
+ "@type": z14.literal("BroadcastEvent").default("BroadcastEvent"),
532
+ isLiveBroadcast: z14.boolean().optional(),
533
+ startDate: z14.string().optional(),
534
+ // ISO 8601
535
+ endDate: z14.string().optional()
536
+ });
537
+ var VideoObjectSchema = z14.object({
538
+ "@type": z14.literal("VideoObject").default("VideoObject"),
539
+ // Required by Google:
540
+ name: z14.string(),
541
+ thumbnailUrl: z14.union([z14.url(), z14.array(z14.url())]),
542
+ uploadDate: z14.string(),
543
+ // ISO 8601 date
544
+ // Recommended by Google:
545
+ description: z14.string().optional(),
546
+ duration: z14.string().optional(),
547
+ // ISO 8601 duration, e.g. "PT1M54S"
548
+ contentUrl: z14.url().optional(),
549
+ embedUrl: z14.url().optional(),
550
+ // Optional:
551
+ expires: z14.string().optional(),
552
+ // ISO 8601 — when video is no longer available
553
+ hasPart: z14.array(ClipSchema).optional(),
554
+ interactionStatistic: z14.object({
555
+ "@type": z14.literal("InteractionCounter").default("InteractionCounter"),
556
+ interactionType: z14.literal("https://schema.org/WatchAction").default("https://schema.org/WatchAction"),
557
+ userInteractionCount: z14.number().int().nonnegative()
558
+ }).optional(),
559
+ regionsAllowed: z14.union([z14.string(), z14.array(z14.string())]).optional(),
560
+ ineligibleRegion: z14.union([z14.string(), z14.array(z14.string())]).optional(),
561
+ requiresSubscription: z14.boolean().optional(),
562
+ isLiveBroadcast: z14.boolean().optional(),
563
+ publication: BroadcastEventSchema.optional(),
564
+ thumbnail: ImageOrUrl.optional()
565
+ });
566
+ var createVideoObject = makeFactory(VideoObjectSchema);
567
+
568
+ // src/types/things/Event.ts
569
+ var EventStatusType = z15.enum([
570
+ "EventScheduled",
571
+ "EventCancelled",
572
+ "EventMovedOnline",
573
+ "EventPostponed",
574
+ "EventRescheduled"
575
+ ]).transform((v) => `https://schema.org/${v}`);
576
+ var EventAttendanceMode = z15.enum([
577
+ "OfflineEventAttendanceMode",
578
+ "OnlineEventAttendanceMode",
579
+ "MixedEventAttendanceMode"
580
+ ]).transform((v) => `https://schema.org/${v}`);
581
+ var PlaceRef = z15.union([
582
+ z15.string(),
583
+ z15.object({
584
+ "@type": z15.literal("Place"),
585
+ name: z15.string().optional(),
586
+ address: z15.union([z15.string(), PostalAddressSchema]).optional(),
587
+ url: z15.url().optional()
588
+ }),
589
+ z15.object({
590
+ "@type": z15.literal("VirtualLocation"),
591
+ url: z15.url(),
592
+ name: z15.string().optional()
593
+ }),
594
+ PostalAddressSchema
595
+ ]);
596
+ var EventSchema = extendThing("Event", {
597
+ // Required by Google:
598
+ name: z15.string(),
599
+ startDate: z15.string(),
600
+ // ISO 8601
601
+ // Recommended by Google:
602
+ endDate: z15.string().optional(),
603
+ // ISO 8601
604
+ location: PlaceRef.optional(),
605
+ eventStatus: EventStatusType.optional(),
606
+ eventAttendanceMode: EventAttendanceMode.optional(),
607
+ offers: z15.union([OfferSchema, z15.array(OfferSchema)]).optional(),
608
+ performer: z15.union([PersonOrOrgRef, z15.array(PersonOrOrgRef)]).optional(),
609
+ organizer: z15.union([PersonOrOrgRef, z15.array(PersonOrOrgRef)]).optional(),
610
+ image: z15.union([ImageOrUrl, z15.array(ImageOrUrl)]).optional(),
611
+ description: z15.string().optional(),
612
+ previousStartDate: z15.string().optional(),
613
+ // ISO 8601 — for rescheduled events
614
+ aggregateRating: AggregateRatingSchema.optional(),
615
+ // Sub-events:
616
+ subEvent: z15.lazy(
617
+ () => z15.array(z15.object({ "@type": z15.string() }).catchall(z15.unknown()))
618
+ ).optional(),
619
+ superEvent: z15.lazy(
620
+ () => z15.object({ "@type": z15.string() }).catchall(z15.unknown())
621
+ ).optional(),
622
+ // Additional:
623
+ inLanguage: z15.union([z15.string(), z15.object({ "@type": z15.literal("Language"), name: z15.string() })]).optional(),
624
+ isAccessibleForFree: z15.boolean().optional(),
625
+ maximumAttendeeCapacity: z15.number().int().nonnegative().optional(),
626
+ remainingAttendeeCapacity: z15.number().int().nonnegative().optional(),
627
+ typicalAgeRange: z15.string().optional(),
628
+ video: VideoObjectSchema.optional()
629
+ });
630
+ var createEvent = makeFactory(EventSchema);
631
+
632
+ // src/types/things/Place.ts
633
+ import { z as z17 } from "zod";
634
+
635
+ // src/types/shared/GeoCoordinates.ts
636
+ import { z as z16 } from "zod";
637
+ var GeoCoordinatesSchema = z16.object({
638
+ "@type": z16.literal("GeoCoordinates").default("GeoCoordinates"),
639
+ latitude: z16.union([z16.number(), z16.string()]),
640
+ longitude: z16.union([z16.number(), z16.string()]),
641
+ elevation: z16.union([z16.number(), z16.string()]).optional()
642
+ });
643
+
644
+ // src/types/things/Place.ts
645
+ var PlaceSchema = extendThing("Place", {
646
+ address: z17.union([z17.string(), PostalAddressSchema]).optional(),
647
+ geo: GeoCoordinatesSchema.optional(),
648
+ hasMap: z17.url().optional(),
649
+ photo: z17.union([ImageOrUrl, z17.array(ImageOrUrl)]).optional(),
650
+ telephone: z17.string().optional(),
651
+ faxNumber: z17.string().optional(),
652
+ openingHoursSpecification: z17.union([
653
+ OpeningHoursSpecificationSchema,
654
+ z17.array(OpeningHoursSpecificationSchema)
655
+ ]).optional(),
656
+ specialOpeningHoursSpecification: z17.union([
657
+ OpeningHoursSpecificationSchema,
658
+ z17.array(OpeningHoursSpecificationSchema)
659
+ ]).optional(),
660
+ maximumAttendeeCapacity: z17.number().int().nonnegative().optional(),
661
+ isAccessibleForFree: z17.boolean().optional(),
662
+ publicAccess: z17.boolean().optional(),
663
+ amenityFeature: z17.array(z17.object({
664
+ "@type": z17.literal("LocationFeatureSpecification").default("LocationFeatureSpecification"),
665
+ name: z17.string(),
666
+ value: z17.union([z17.boolean(), z17.string(), z17.number()])
667
+ })).optional(),
668
+ containedInPlace: z17.lazy(
669
+ () => z17.object({ "@type": z17.string(), name: z17.string().optional() }).catchall(z17.unknown())
670
+ ).optional()
671
+ });
672
+ var createPlace = makeFactory(PlaceSchema);
673
+
674
+ // src/types/things/LocalBusiness.ts
675
+ import { z as z18 } from "zod";
676
+ var LocalBusinessSchema = PlaceSchema.extend({
677
+ "@type": z18.union([
678
+ z18.literal("LocalBusiness"),
679
+ z18.literal("Restaurant"),
680
+ z18.literal("Store"),
681
+ z18.literal("FoodEstablishment"),
682
+ z18.literal("HealthAndBeautyBusiness"),
683
+ z18.literal("MedicalBusiness"),
684
+ z18.literal("FinancialService"),
685
+ z18.literal("LegalService"),
686
+ z18.literal("RealEstateAgent"),
687
+ z18.literal("AutoDealer"),
688
+ z18.literal("DaySpa"),
689
+ z18.literal("HairSalon"),
690
+ z18.literal("Hotel"),
691
+ z18.literal("LodgingBusiness"),
692
+ z18.literal("GroceryStore"),
693
+ z18.literal("ShoppingCenter"),
694
+ z18.literal("TravelAgency")
695
+ ]).default("LocalBusiness"),
696
+ // Business identity:
697
+ legalName: z18.string().optional(),
698
+ email: z18.email().optional(),
699
+ logo: ImageOrUrl.optional(),
700
+ contactPoint: z18.union([ContactPointSchema, z18.array(ContactPointSchema)]).optional(),
701
+ // Ratings & reviews:
702
+ aggregateRating: z18.union([AggregateRatingSchema, EmployerAggregateRatingSchema]).optional(),
703
+ review: z18.union([ReviewSchema, z18.array(ReviewSchema)]).optional(),
704
+ // Pricing:
705
+ priceRange: z18.string().optional(),
706
+ // e.g. "$$$"
707
+ currenciesAccepted: z18.string().optional(),
708
+ paymentAccepted: z18.string().optional(),
709
+ // Food establishment specific:
710
+ servesCuisine: z18.union([z18.string(), z18.array(z18.string())]).optional(),
711
+ hasMenu: z18.url().optional(),
712
+ acceptsReservations: z18.union([z18.boolean(), z18.url()]).optional(),
713
+ // Merchant signals:
714
+ vatID: z18.string().optional(),
715
+ iso6523Code: z18.string().optional(),
716
+ hasMerchantReturnPolicy: MerchantReturnPolicySchema.optional(),
717
+ sameAs: z18.union([z18.url(), z18.array(z18.url())]).optional(),
718
+ // Departments (nested LocalBusiness):
719
+ department: z18.lazy(
720
+ () => z18.union([
721
+ z18.object({ "@type": z18.string() }).catchall(z18.unknown()),
722
+ z18.array(z18.object({ "@type": z18.string() }).catchall(z18.unknown()))
723
+ ])
724
+ ).optional(),
725
+ // Opening hours in string format (alternative to openingHoursSpecification):
726
+ openingHours: z18.union([z18.string(), z18.array(z18.string())]).optional()
727
+ });
728
+ var createLocalBusiness = makeFactory(LocalBusinessSchema);
729
+ var createRestaurant = makeFactory(
730
+ LocalBusinessSchema.extend({ "@type": z18.literal("Restaurant").default("Restaurant") })
731
+ );
732
+ var createHotel = makeFactory(
733
+ LocalBusinessSchema.extend({ "@type": z18.literal("Hotel").default("Hotel") })
734
+ );
735
+
736
+ // src/types/things/Movie.ts
737
+ import { z as z19 } from "zod";
738
+ var MovieSchema = extendThing("Movie", {
739
+ // Recommended by Google:
740
+ director: z19.union([PersonOrOrgRef, z19.array(PersonOrOrgRef)]).optional(),
741
+ actor: z19.union([PersonOrOrgRef, z19.array(PersonOrOrgRef)]).optional(),
742
+ author: z19.union([PersonOrOrgRef, z19.array(PersonOrOrgRef)]).optional(),
743
+ producer: PersonOrOrgRef.optional(),
744
+ musicBy: PersonOrOrgRef.optional(),
745
+ duration: z19.string().optional(),
746
+ // ISO 8601, e.g. "PT2H15M"
747
+ dateCreated: z19.string().optional(),
748
+ // ISO 8601
749
+ datePublished: z19.string().optional(),
750
+ // ISO 8601
751
+ countryOfOrigin: z19.string().optional(),
752
+ // ISO 3166
753
+ inLanguage: z19.union([
754
+ z19.string(),
755
+ z19.object({ "@type": z19.literal("Language"), name: z19.string() })
756
+ ]).optional(),
757
+ aggregateRating: AggregateRatingSchema.optional(),
758
+ review: z19.union([ReviewSchema, z19.array(ReviewSchema)]).optional(),
759
+ trailer: VideoObjectSchema.optional(),
760
+ image: z19.union([ImageOrUrl, z19.array(ImageOrUrl)]).optional(),
761
+ // Classification:
762
+ contentRating: z19.string().optional(),
763
+ // e.g. "MPAA PG-13"
764
+ genre: z19.union([z19.string(), z19.array(z19.string())]).optional(),
765
+ // For carousels: itemListElement links
766
+ sameAs: z19.union([z19.url(), z19.array(z19.url())]).optional()
767
+ });
768
+ var createMovie = makeFactory(MovieSchema);
769
+
770
+ // src/types/creative-works/Book.ts
771
+ import { z as z20 } from "zod";
772
+ var BookFormatType = z20.enum([
773
+ "EBook",
774
+ "Hardcover",
775
+ "Paperback",
776
+ "AudioBook",
777
+ "GraphicNovel"
778
+ ]);
779
+ var EntryPointSchema = z20.object({
780
+ "@type": z20.literal("EntryPoint").default("EntryPoint"),
781
+ /** URL template with optional {isbn} / {id} placeholder, or a plain URL */
782
+ urlTemplate: z20.string(),
783
+ /** MIME type of the action target */
784
+ encodingType: z20.string().optional(),
785
+ /** HTTP method */
786
+ httpMethod: z20.string().optional()
787
+ });
788
+ var ReadActionSchema = z20.object({
789
+ "@type": z20.literal("ReadAction").default("ReadAction"),
790
+ /** Where the book can be read */
791
+ target: z20.union([EntryPointSchema, z20.string()]),
792
+ /** Offer describing subscription / purchase required to read */
793
+ expectsAcceptanceOf: OfferSchema.optional()
794
+ });
795
+ var BorrowActionSchema = z20.object({
796
+ "@type": z20.literal("BorrowAction").default("BorrowAction"),
797
+ /** Library system or library lending this book */
798
+ lender: z20.object({
799
+ "@type": z20.union([
800
+ z20.literal("LibrarySystem"),
801
+ z20.literal("Library")
802
+ ]),
803
+ name: z20.string(),
804
+ url: z20.url().optional(),
805
+ /** Unique identifier for the library system */
806
+ "@id": z20.string().optional()
807
+ }),
808
+ /** Where the borrow action is performed */
809
+ target: z20.union([EntryPointSchema, z20.string()])
810
+ });
811
+ var BookEditionSchema = z20.object({
812
+ "@type": z20.literal("Book").default("Book"),
813
+ /** Unique stable URL identifying this edition */
814
+ "@id": z20.string().optional(),
815
+ /** Edition title — may differ from the work title */
816
+ name: z20.string().optional(),
817
+ /** Physical/digital format */
818
+ bookFormat: BookFormatType.optional(),
819
+ /** BCP 47 language tag, e.g. "en", "fr" */
820
+ inLanguage: z20.string().optional(),
821
+ /** ISBN-13 preferred; ISBN-10 also accepted */
822
+ isbn: z20.string().optional(),
823
+ /** OCLC number (for library systems) */
824
+ sameAs: z20.union([z20.string(), z20.array(z20.string())]).optional(),
825
+ /** Edition number, e.g. "2nd" */
826
+ bookEdition: z20.string().optional(),
827
+ /** Publication date for this edition */
828
+ datePublished: z20.string().optional(),
829
+ /** Landing page for this edition */
830
+ url: z20.url().optional(),
831
+ /** Authors of this edition (may differ from work author) */
832
+ author: z20.union([PersonOrOrgRef, z20.array(PersonOrOrgRef)]).optional(),
833
+ /** ReadAction or BorrowAction for Google Book Actions */
834
+ potentialAction: z20.union([
835
+ ReadActionSchema,
836
+ BorrowActionSchema,
837
+ z20.array(z20.union([ReadActionSchema, BorrowActionSchema]))
838
+ ]).optional(),
839
+ /** Offer — purchase price */
840
+ offers: z20.union([OfferSchema, z20.array(OfferSchema)]).optional()
841
+ });
842
+ var BookSchema = z20.object({
843
+ "@type": z20.literal("Book").default("Book"),
844
+ /** Stable URL identifying this work */
845
+ "@id": z20.string().optional(),
846
+ name: z20.string(),
847
+ /** Primary author(s) of the work */
848
+ author: z20.union([PersonOrOrgRef, z20.array(PersonOrOrgRef)]),
849
+ /** Canonical URL for the book's landing page */
850
+ url: z20.url().optional(),
851
+ /** Cover image */
852
+ image: z20.union([ImageOrUrl, z20.array(ImageOrUrl)]).optional(),
853
+ description: z20.string().optional(),
854
+ /** ISBN of the primary edition */
855
+ isbn: z20.string().optional(),
856
+ /** Same-as links (e.g., Open Library, WorldCat) */
857
+ sameAs: z20.union([z20.string(), z20.array(z20.string())]).optional(),
858
+ /** Specific editions — each may have ReadAction / BorrowAction */
859
+ workExample: z20.union([BookEditionSchema, z20.array(BookEditionSchema)]).optional(),
860
+ /** Publisher of the primary edition */
861
+ publisher: z20.object({
862
+ "@type": z20.union([z20.literal("Organization"), z20.literal("Person")]),
863
+ name: z20.string(),
864
+ url: z20.url().optional()
865
+ }).optional(),
866
+ /** Number of pages */
867
+ numberOfPages: z20.number().int().positive().optional(),
868
+ /** Original publication year */
869
+ datePublished: z20.string().optional(),
870
+ /** Genres */
871
+ genre: z20.union([z20.string(), z20.array(z20.string())]).optional(),
872
+ /** BCP 47 language tag */
873
+ inLanguage: z20.string().optional(),
874
+ /** Aggregate rating across editions */
875
+ aggregateRating: z20.lazy(
876
+ () => z20.object({ "@type": z20.string() }).catchall(z20.unknown())
877
+ ).optional()
878
+ });
879
+ var createBook = makeFactory(BookSchema);
880
+
881
+ // src/types/creative-works/Article.ts
882
+ import { z as z22 } from "zod";
883
+
884
+ // src/types/creative-works/CreativeWork.ts
885
+ import { z as z21 } from "zod";
886
+ var CreativeWorkSchema = extendThing("CreativeWork", {
887
+ author: PersonOrOrgRef.optional(),
888
+ publisher: PersonOrOrgRef.optional(),
889
+ datePublished: z21.string().optional(),
890
+ // ISO 8601
891
+ dateModified: z21.string().optional(),
892
+ // ISO 8601
893
+ headline: z21.string().max(110).optional(),
894
+ // Google recommends max 110 chars
895
+ keywords: z21.union([z21.string(), z21.array(z21.string())]).optional(),
896
+ inLanguage: z21.union([
897
+ z21.string(),
898
+ // BCP 47, e.g. "en-US"
899
+ z21.object({ "@type": z21.literal("Language"), name: z21.string() })
900
+ ]).optional(),
901
+ license: z21.url().optional(),
902
+ thumbnailUrl: z21.url().optional(),
903
+ isAccessibleForFree: z21.boolean().optional(),
904
+ image: z21.union([ImageOrUrl, z21.array(ImageOrUrl)]).optional(),
905
+ // Paywalled content support:
906
+ hasPart: z21.array(z21.object({
907
+ "@type": z21.string(),
908
+ isAccessibleForFree: z21.boolean().optional(),
909
+ cssSelector: z21.string().optional()
910
+ })).optional(),
911
+ // For subscription / paywalled content
912
+ isPartOf: z21.object({
913
+ "@type": z21.string(),
914
+ name: z21.string().optional()
915
+ }).optional(),
916
+ text: z21.string().optional(),
917
+ abstract: z21.string().optional(),
918
+ encodingFormat: z21.string().optional(),
919
+ // MIME type
920
+ contentUrl: z21.url().optional(),
921
+ copyrightYear: z21.number().int().optional(),
922
+ copyrightHolder: PersonOrOrgRef.optional()
923
+ });
924
+
925
+ // src/types/creative-works/Article.ts
926
+ var ArticleSchema = CreativeWorkSchema.extend({
927
+ "@type": z22.literal("Article").default("Article"),
928
+ articleBody: z22.string().optional(),
929
+ articleSection: z22.string().optional(),
930
+ wordCount: z22.number().int().nonnegative().optional(),
931
+ // Google Article requires image to be at least 1200px wide
932
+ image: z22.union([ImageOrUrl, z22.array(ImageOrUrl)]).optional(),
933
+ video: z22.union([VideoObjectSchema, z22.array(VideoObjectSchema)]).optional(),
934
+ // Speakable for Article (Google Assistant)
935
+ speakable: z22.object({
936
+ "@type": z22.literal("SpeakableSpecification").default("SpeakableSpecification"),
937
+ cssSelector: z22.union([z22.string(), z22.array(z22.string())]).optional(),
938
+ xpath: z22.union([z22.string(), z22.array(z22.string())]).optional()
939
+ }).optional()
940
+ });
941
+ var NewsArticleSchema = ArticleSchema.extend({
942
+ "@type": z22.literal("NewsArticle").default("NewsArticle"),
943
+ dateline: z22.string().optional(),
944
+ printColumn: z22.string().optional(),
945
+ printEdition: z22.string().optional(),
946
+ printPage: z22.string().optional(),
947
+ printSection: z22.string().optional()
948
+ });
949
+ var BlogPostingSchema = ArticleSchema.extend({
950
+ "@type": z22.literal("BlogPosting").default("BlogPosting"),
951
+ sharedContent: z22.lazy(
952
+ () => z22.object({ "@type": z22.string() }).passthrough()
953
+ ).optional()
954
+ });
955
+ var createArticle = makeFactory(ArticleSchema);
956
+ var createNewsArticle = makeFactory(NewsArticleSchema);
957
+ var createBlogPosting = makeFactory(BlogPostingSchema);
958
+
959
+ // src/types/creative-works/WebPage.ts
960
+ import { z as z23 } from "zod";
961
+ var WebPageSchema = CreativeWorkSchema.extend({
962
+ "@type": z23.literal("WebPage").default("WebPage"),
963
+ breadcrumb: z23.lazy(
964
+ () => z23.object({ "@type": z23.literal("BreadcrumbList") }).catchall(z23.unknown())
965
+ ).optional(),
966
+ lastReviewed: z23.string().optional(),
967
+ reviewedBy: PersonOrOrgRef.optional(),
968
+ speakable: z23.object({
969
+ "@type": z23.literal("SpeakableSpecification").default("SpeakableSpecification"),
970
+ cssSelector: z23.union([z23.string(), z23.array(z23.string())]).optional(),
971
+ xpath: z23.union([z23.string(), z23.array(z23.string())]).optional()
972
+ }).optional(),
973
+ significantLink: z23.union([z23.url(), z23.array(z23.url())]).optional(),
974
+ mainContentOfPage: z23.object({ "@type": z23.string() }).catchall(z23.unknown()).optional(),
975
+ primaryImageOfPage: z23.object({ "@type": z23.string() }).catchall(z23.unknown()).optional(),
976
+ relatedLink: z23.union([z23.url(), z23.array(z23.url())]).optional()
977
+ });
978
+ var createWebPage = makeFactory(WebPageSchema);
979
+
980
+ // src/types/creative-works/WebSite.ts
981
+ import { z as z24 } from "zod";
982
+ var WebSiteSchema = CreativeWorkSchema.extend({
983
+ "@type": z24.literal("WebSite").default("WebSite"),
984
+ url: z24.url().optional(),
985
+ name: z24.string().optional(),
986
+ /**
987
+ * Sitelinks Searchbox via SearchAction.
988
+ * @deprecated Google removed the Sitelinks Searchbox feature in November 2024.
989
+ * This field is still valid JSON-LD and harmless to include, but Google no
990
+ * longer displays a search box in branded search results.
991
+ * See: https://developers.google.com/search/blog/2024/11/retiring-sitelinks-searchbox
992
+ */
993
+ potentialAction: z24.object({
994
+ "@type": z24.literal("SearchAction"),
995
+ target: z24.union([
996
+ z24.string(),
997
+ z24.object({
998
+ "@type": z24.literal("EntryPoint"),
999
+ urlTemplate: z24.string()
1000
+ })
1001
+ ]),
1002
+ "query-input": z24.string().optional()
1003
+ }).optional(),
1004
+ // Content language(s)
1005
+ inLanguage: z24.union([z24.string(), z24.array(z24.string())]).optional(),
1006
+ // Authorship / ownership
1007
+ publisher: PersonOrOrgRef.optional(),
1008
+ // Site-level metadata
1009
+ copyrightYear: z24.number().int().optional(),
1010
+ // isPartOf — rarely used for WebSite itself but allowed
1011
+ isPartOf: z24.lazy(
1012
+ () => z24.object({ "@type": z24.string() }).catchall(z24.unknown())
1013
+ ).optional()
1014
+ });
1015
+ var createWebSite = makeFactory(WebSiteSchema);
1016
+
1017
+ // src/types/creative-works/Dataset.ts
1018
+ import { z as z25 } from "zod";
1019
+ var PropertyValueSchema = z25.object({
1020
+ "@type": z25.literal("PropertyValue").default("PropertyValue"),
1021
+ propertyID: z25.string().optional(),
1022
+ // e.g. "DOI", "SPDX"
1023
+ name: z25.string().optional(),
1024
+ value: z25.union([z25.string(), z25.number()]),
1025
+ url: z25.url().optional(),
1026
+ description: z25.string().optional()
1027
+ });
1028
+ var DatasetSchema = CreativeWorkSchema.extend({
1029
+ "@type": z25.literal("Dataset").default("Dataset"),
1030
+ // Required by Google:
1031
+ name: z25.string(),
1032
+ description: z25.string(),
1033
+ // Recommended by Google:
1034
+ url: z25.url().optional(),
1035
+ sameAs: z25.union([z25.url(), z25.array(z25.url())]).optional(),
1036
+ identifier: z25.union([
1037
+ z25.string(),
1038
+ PropertyValueSchema,
1039
+ z25.array(z25.union([z25.string(), PropertyValueSchema]))
1040
+ ]).optional(),
1041
+ keywords: z25.union([z25.string(), z25.array(z25.string())]).optional(),
1042
+ license: z25.url().optional(),
1043
+ isAccessibleForFree: z25.boolean().optional(),
1044
+ creator: z25.union([PersonOrOrgRef, z25.array(PersonOrOrgRef)]).optional(),
1045
+ citation: z25.union([z25.string(), z25.array(z25.string())]).optional(),
1046
+ variableMeasured: z25.union([z25.string(), z25.array(z25.string())]).optional(),
1047
+ measurementTechnique: z25.union([z25.string(), z25.array(z25.string())]).optional(),
1048
+ temporalCoverage: z25.string().optional(),
1049
+ // ISO 8601 or date range string
1050
+ spatialCoverage: z25.union([
1051
+ z25.string(),
1052
+ z25.object({ "@type": z25.literal("Place"), name: z25.string() })
1053
+ ]).optional(),
1054
+ distribution: z25.array(z25.object({
1055
+ "@type": z25.literal("DataDownload").default("DataDownload"),
1056
+ encodingFormat: z25.string(),
1057
+ // MIME type or format name
1058
+ contentUrl: z25.url(),
1059
+ name: z25.string().optional(),
1060
+ description: z25.string().optional()
1061
+ })).optional(),
1062
+ includedInDataCatalog: z25.object({
1063
+ "@type": z25.literal("DataCatalog").default("DataCatalog"),
1064
+ name: z25.string(),
1065
+ url: z25.url().optional()
1066
+ }).optional(),
1067
+ datePublished: z25.string().optional(),
1068
+ // ISO 8601
1069
+ dateModified: z25.string().optional(),
1070
+ version: z25.union([z25.string(), z25.number()]).optional()
1071
+ });
1072
+ var createDataset = makeFactory(DatasetSchema);
1073
+
1074
+ // src/types/creative-works/Recipe.ts
1075
+ import { z as z27 } from "zod";
1076
+
1077
+ // src/types/shared/HowToStep.ts
1078
+ import { z as z26 } from "zod";
1079
+ var HowToStepSchema = z26.object({
1080
+ "@type": z26.literal("HowToStep").default("HowToStep"),
1081
+ name: z26.string().optional(),
1082
+ // Step title (avoid "Step 1" format per Google)
1083
+ text: z26.string(),
1084
+ // Step description
1085
+ url: z26.string().url().optional(),
1086
+ // Anchor link to step
1087
+ image: ImageOrUrl.optional()
1088
+ });
1089
+ var HowToSectionSchema = z26.object({
1090
+ "@type": z26.literal("HowToSection").default("HowToSection"),
1091
+ name: z26.string(),
1092
+ itemListElement: z26.array(HowToStepSchema),
1093
+ description: z26.string().optional()
1094
+ });
1095
+
1096
+ // src/types/creative-works/Recipe.ts
1097
+ var NutritionInformationSchema = z27.object({
1098
+ "@type": z27.literal("NutritionInformation").default("NutritionInformation"),
1099
+ calories: z27.string().optional(),
1100
+ // e.g. "270 calories"
1101
+ carbohydrateContent: z27.string().optional(),
1102
+ // e.g. "20 grams"
1103
+ cholesterolContent: z27.string().optional(),
1104
+ fatContent: z27.string().optional(),
1105
+ fiberContent: z27.string().optional(),
1106
+ proteinContent: z27.string().optional(),
1107
+ saturatedFatContent: z27.string().optional(),
1108
+ servingSize: z27.string().optional(),
1109
+ sodiumContent: z27.string().optional(),
1110
+ sugarContent: z27.string().optional(),
1111
+ transFatContent: z27.string().optional(),
1112
+ unsaturatedFatContent: z27.string().optional()
1113
+ });
1114
+ var RecipeSchema = CreativeWorkSchema.extend({
1115
+ "@type": z27.literal("Recipe").default("Recipe"),
1116
+ // Required by Google:
1117
+ name: z27.string(),
1118
+ image: z27.union([ImageOrUrl, z27.array(ImageOrUrl)]),
1119
+ // Recommended by Google:
1120
+ author: z27.union([PersonOrOrgRef, z27.array(PersonOrOrgRef)]).optional(),
1121
+ datePublished: z27.string().optional(),
1122
+ // ISO 8601 date
1123
+ description: z27.string().optional(),
1124
+ prepTime: z27.string().optional(),
1125
+ // ISO 8601 duration, e.g. "PT15M"
1126
+ cookTime: z27.string().optional(),
1127
+ // ISO 8601 duration
1128
+ totalTime: z27.string().optional(),
1129
+ // ISO 8601 duration
1130
+ recipeYield: z27.union([z27.string(), z27.number(), z27.array(z27.string())]).optional(),
1131
+ recipeCategory: z27.string().optional(),
1132
+ // e.g. "Dessert", "Dinner"
1133
+ recipeCuisine: z27.string().optional(),
1134
+ // e.g. "Italian", "French"
1135
+ recipeIngredient: z27.array(z27.string()).optional(),
1136
+ recipeInstructions: z27.array(
1137
+ z27.union([z27.string(), HowToStepSchema, HowToSectionSchema])
1138
+ ).optional(),
1139
+ nutrition: NutritionInformationSchema.optional(),
1140
+ video: z27.union([VideoObjectSchema, z27.array(VideoObjectSchema)]).optional(),
1141
+ aggregateRating: AggregateRatingSchema.optional(),
1142
+ review: z27.union([ReviewSchema, z27.array(ReviewSchema)]).optional(),
1143
+ keywords: z27.union([z27.string(), z27.array(z27.string())]).optional(),
1144
+ cookingMethod: z27.string().optional(),
1145
+ suitableForDiet: z27.union([z27.string(), z27.array(z27.string())]).optional(),
1146
+ // schema.org enum URL
1147
+ estimatedCost: z27.string().optional()
1148
+ });
1149
+ var createRecipe = makeFactory(RecipeSchema);
1150
+
1151
+ // src/types/creative-works/Course.ts
1152
+ import { z as z28 } from "zod";
1153
+ var CourseInstanceSchema = z28.object({
1154
+ "@type": z28.literal("CourseInstance").default("CourseInstance"),
1155
+ courseMode: z28.union([z28.string(), z28.array(z28.string())]),
1156
+ // "online", "onsite", "blended"
1157
+ instructor: z28.union([PersonOrOrgRef, z28.array(PersonOrOrgRef)]).optional(),
1158
+ startDate: z28.string().optional(),
1159
+ // ISO 8601
1160
+ endDate: z28.string().optional(),
1161
+ // ISO 8601
1162
+ location: z28.union([z28.string(), PostalAddressSchema]).optional(),
1163
+ offers: z28.union([OfferSchema, z28.array(OfferSchema)]).optional(),
1164
+ courseWorkload: z28.string().optional(),
1165
+ // ISO 8601 duration, e.g. "PT10H"
1166
+ courseSchedule: z28.object({
1167
+ "@type": z28.literal("Schedule").default("Schedule"),
1168
+ repeatFrequency: z28.string().optional(),
1169
+ // e.g. "P1W"
1170
+ repeatCount: z28.number().optional(),
1171
+ startDate: z28.string().optional(),
1172
+ endDate: z28.string().optional()
1173
+ }).optional()
1174
+ });
1175
+ var CourseSchema = CreativeWorkSchema.extend({
1176
+ "@type": z28.literal("Course").default("Course"),
1177
+ // Required by Google:
1178
+ name: z28.string(),
1179
+ description: z28.string(),
1180
+ // Recommended by Google:
1181
+ provider: z28.union([PersonOrOrgRef, z28.array(PersonOrOrgRef)]).optional(),
1182
+ hasCourseInstance: z28.union([CourseInstanceSchema, z28.array(CourseInstanceSchema)]).optional(),
1183
+ // Optional:
1184
+ coursePrerequisites: z28.union([z28.string(), z28.array(z28.string())]).optional(),
1185
+ educationalCredentialAwarded: z28.union([
1186
+ z28.string(),
1187
+ z28.object({
1188
+ "@type": z28.literal("EducationalOccupationalCredential").default("EducationalOccupationalCredential"),
1189
+ name: z28.string(),
1190
+ url: z28.url().optional()
1191
+ })
1192
+ ]).optional(),
1193
+ occupationalCredentialAwarded: z28.union([z28.string(), z28.array(z28.string())]).optional(),
1194
+ numberOfCredits: z28.union([
1195
+ z28.number(),
1196
+ z28.object({
1197
+ "@type": z28.literal("StructuredValue").default("StructuredValue"),
1198
+ value: z28.number()
1199
+ })
1200
+ ]).optional(),
1201
+ financialAidEligible: z28.union([z28.string(), z28.boolean()]).optional(),
1202
+ aggregateRating: AggregateRatingSchema.optional(),
1203
+ image: z28.union([ImageOrUrl, z28.array(ImageOrUrl)]).optional(),
1204
+ offers: z28.union([OfferSchema, z28.array(OfferSchema)]).optional(),
1205
+ inLanguage: z28.union([z28.string(), z28.array(z28.string())]).optional(),
1206
+ syllabusSections: z28.array(z28.object({
1207
+ "@type": z28.literal("Syllabus").default("Syllabus"),
1208
+ name: z28.string(),
1209
+ description: z28.string().optional()
1210
+ })).optional()
1211
+ });
1212
+ var createCourse = makeFactory(CourseSchema);
1213
+
1214
+ // src/types/creative-works/SoftwareApplication.ts
1215
+ import { z as z29 } from "zod";
1216
+ var ApplicationCategory = z29.enum([
1217
+ "GameApplication",
1218
+ "SocialNetworkingApplication",
1219
+ "TravelApplication",
1220
+ "ShoppingApplication",
1221
+ "SportsApplication",
1222
+ "LifestyleApplication",
1223
+ "BusinessApplication",
1224
+ "DesignApplication",
1225
+ "DeveloperApplication",
1226
+ "DriverApplication",
1227
+ "EducationalApplication",
1228
+ "HealthApplication",
1229
+ "FinanceApplication",
1230
+ "SecurityApplication",
1231
+ "BrowserApplication",
1232
+ "CommunicationApplication",
1233
+ "DesktopEnhancementApplication",
1234
+ "EntertainmentApplication",
1235
+ "MultimediaApplication",
1236
+ "HomeApplication",
1237
+ "UtilitiesApplication",
1238
+ "ReferenceApplication"
1239
+ ]);
1240
+ var SoftwareApplicationSchema = CreativeWorkSchema.extend({
1241
+ "@type": z29.union([
1242
+ z29.literal("SoftwareApplication"),
1243
+ z29.literal("MobileApplication"),
1244
+ z29.literal("WebApplication"),
1245
+ z29.literal("VideoGame")
1246
+ ]).default("SoftwareApplication"),
1247
+ // Required by Google:
1248
+ name: z29.string(),
1249
+ // Recommended by Google:
1250
+ operatingSystem: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1251
+ applicationCategory: z29.union([ApplicationCategory, z29.string()]).optional(),
1252
+ offers: z29.union([OfferSchema, z29.array(OfferSchema)]).optional(),
1253
+ aggregateRating: AggregateRatingSchema.optional(),
1254
+ review: z29.union([ReviewSchema, z29.array(ReviewSchema)]).optional(),
1255
+ // Optional:
1256
+ softwareVersion: z29.string().optional(),
1257
+ fileSize: z29.string().optional(),
1258
+ downloadUrl: z29.url().optional(),
1259
+ screenshot: z29.union([ImageOrUrl, z29.array(ImageOrUrl)]).optional(),
1260
+ featureList: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1261
+ installUrl: z29.url().optional(),
1262
+ softwareRequirements: z29.string().optional(),
1263
+ permissions: z29.string().optional(),
1264
+ // WebApplication specific:
1265
+ browserRequirements: z29.string().optional(),
1266
+ // MobileApplication specific:
1267
+ countriesSupported: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1268
+ countriesNotSupported: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1269
+ availableOnDevice: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1270
+ // VideoGame specific:
1271
+ gamePlatform: z29.union([z29.string(), z29.array(z29.string())]).optional(),
1272
+ playMode: z29.string().optional(),
1273
+ genre: z29.union([z29.string(), z29.array(z29.string())]).optional()
1274
+ });
1275
+ var createSoftwareApplication = makeFactory(SoftwareApplicationSchema);
1276
+ var createMobileApplication = makeFactory(
1277
+ SoftwareApplicationSchema.extend({
1278
+ "@type": z29.literal("MobileApplication").default("MobileApplication")
1279
+ })
1280
+ );
1281
+ var createWebApplication = makeFactory(
1282
+ SoftwareApplicationSchema.extend({
1283
+ "@type": z29.literal("WebApplication").default("WebApplication")
1284
+ })
1285
+ );
1286
+
1287
+ // src/types/creative-works/MathSolver.ts
1288
+ import { z as z30 } from "zod";
1289
+ var SolveMathActionSchema = z30.object({
1290
+ "@type": z30.literal("SolveMathAction").default("SolveMathAction"),
1291
+ eduQuestionType: z30.string().optional(),
1292
+ // e.g. "Algebra", "Calculus"
1293
+ mathExpression: z30.string().optional(),
1294
+ target: z30.object({
1295
+ "@type": z30.literal("EntryPoint").default("EntryPoint"),
1296
+ urlTemplate: z30.string().optional(),
1297
+ actionAccessibilityRequirement: z30.object({
1298
+ "@type": z30.literal("ActionAccessSpecification").default("ActionAccessSpecification"),
1299
+ requiresSubscription: z30.boolean().optional()
1300
+ }).optional()
1301
+ }).optional()
1302
+ });
1303
+ var MathSolverSchema = CreativeWorkSchema.extend({
1304
+ "@type": z30.literal("MathSolver").default("MathSolver"),
1305
+ name: z30.string(),
1306
+ url: z30.url().optional(),
1307
+ potentialAction: z30.union([SolveMathActionSchema, z30.array(SolveMathActionSchema)]).optional(),
1308
+ mathExpression: z30.union([z30.string(), z30.array(z30.string())]).optional(),
1309
+ educationalLevel: z30.string().optional(),
1310
+ teaches: z30.union([z30.string(), z30.array(z30.string())]).optional()
1311
+ });
1312
+ var createMathSolver = makeFactory(MathSolverSchema);
1313
+
1314
+ // src/types/intangibles/Language.ts
1315
+ import { z as z31 } from "zod";
1316
+ var LanguageSchema = extendThing("Language", {
1317
+ // No additional properties beyond Thing for Language
1318
+ // But you can attach any Thing props: name, alternateName, url, etc.
1319
+ });
1320
+ var createLanguage = makeFactory(LanguageSchema);
1321
+ var PronounceableTextSchema = z31.object({
1322
+ "@type": z31.literal("PronounceableText").default("PronounceableText"),
1323
+ textValue: z31.string(),
1324
+ // Accepts either a BCP 47 string like "en-US" or a full Language object
1325
+ inLanguage: z31.union([z31.string(), LanguageSchema]).optional(),
1326
+ phoneticText: z31.string().optional(),
1327
+ speechToTextMarkup: z31.string().optional()
1328
+ });
1329
+ var createPronounceableText = makeFactory(PronounceableTextSchema);
1330
+
1331
+ // src/types/intangibles/JobPosting.ts
1332
+ import { z as z33 } from "zod";
1333
+
1334
+ // src/types/shared/MonetaryAmount.ts
1335
+ import { z as z32 } from "zod";
1336
+ var MonetaryAmountSchema = z32.object({
1337
+ "@type": z32.literal("MonetaryAmount").default("MonetaryAmount"),
1338
+ currency: z32.string().length(3),
1339
+ // ISO 4217, e.g. "USD"
1340
+ value: z32.union([
1341
+ z32.number(),
1342
+ z32.object({
1343
+ "@type": z32.literal("QuantitativeValue").default("QuantitativeValue"),
1344
+ value: z32.number().optional(),
1345
+ minValue: z32.number().optional(),
1346
+ maxValue: z32.number().optional(),
1347
+ unitText: z32.string().optional()
1348
+ // e.g. "HOUR", "MONTH", "YEAR"
1349
+ })
1350
+ ]).optional(),
1351
+ minValue: z32.number().optional(),
1352
+ maxValue: z32.number().optional()
1353
+ });
1354
+ var PriceSpecificationSchema = z32.object({
1355
+ "@type": z32.literal("PriceSpecification").default("PriceSpecification"),
1356
+ price: z32.union([z32.number(), z32.string()]),
1357
+ priceCurrency: z32.string().length(3),
1358
+ // ISO 4217
1359
+ minPrice: z32.number().optional(),
1360
+ maxPrice: z32.number().optional(),
1361
+ validFrom: z32.string().optional(),
1362
+ // ISO 8601
1363
+ validThrough: z32.string().optional(),
1364
+ eligibleQuantity: z32.object({
1365
+ "@type": z32.literal("QuantitativeValue").default("QuantitativeValue"),
1366
+ value: z32.number().optional(),
1367
+ minValue: z32.number().optional(),
1368
+ maxValue: z32.number().optional()
1369
+ }).optional()
1370
+ });
1371
+
1372
+ // src/types/intangibles/JobPosting.ts
1373
+ var EmploymentType = z33.enum([
1374
+ "FULL_TIME",
1375
+ "PART_TIME",
1376
+ "CONTRACTOR",
1377
+ "TEMPORARY",
1378
+ "INTERN",
1379
+ "VOLUNTEER",
1380
+ "PER_DIEM",
1381
+ "OTHER"
1382
+ ]);
1383
+ var HiringOrgRef = z33.object({
1384
+ "@type": z33.union([z33.literal("Organization"), z33.literal("LocalBusiness")]).default("Organization"),
1385
+ name: z33.string(),
1386
+ sameAs: z33.url().optional(),
1387
+ logo: ImageOrUrl.optional(),
1388
+ url: z33.url().optional()
1389
+ });
1390
+ var JobLocationRef = z33.object({
1391
+ "@type": z33.literal("Place").default("Place"),
1392
+ address: z33.union([z33.string(), PostalAddressSchema])
1393
+ });
1394
+ var JobPostingSchema = z33.object({
1395
+ "@type": z33.literal("JobPosting").default("JobPosting"),
1396
+ // Required by Google:
1397
+ title: z33.string(),
1398
+ description: z33.string(),
1399
+ hiringOrganization: HiringOrgRef,
1400
+ jobLocation: z33.union([JobLocationRef, z33.array(JobLocationRef)]).optional(),
1401
+ datePosted: z33.string(),
1402
+ // ISO 8601 date
1403
+ // Recommended by Google:
1404
+ validThrough: z33.string().optional(),
1405
+ // ISO 8601 datetime
1406
+ employmentType: z33.union([EmploymentType, z33.array(EmploymentType)]).optional(),
1407
+ baseSalary: MonetaryAmountSchema.optional(),
1408
+ jobLocationType: z33.string().optional(),
1409
+ // "TELECOMMUTE" for remote
1410
+ applicantLocationRequirements: z33.union([
1411
+ z33.object({ "@type": z33.string(), name: z33.string() }),
1412
+ z33.array(z33.object({ "@type": z33.string(), name: z33.string() }))
1413
+ ]).optional(),
1414
+ directApply: z33.boolean().optional(),
1415
+ // Optional:
1416
+ identifier: z33.object({
1417
+ "@type": z33.literal("PropertyValue").default("PropertyValue"),
1418
+ name: z33.string().optional(),
1419
+ value: z33.union([z33.string(), z33.number()])
1420
+ }).optional(),
1421
+ experienceRequirements: z33.union([
1422
+ z33.string(),
1423
+ z33.object({
1424
+ "@type": z33.literal("OccupationalExperienceRequirements").default("OccupationalExperienceRequirements"),
1425
+ monthsOfExperience: z33.number()
1426
+ })
1427
+ ]).optional(),
1428
+ educationRequirements: z33.union([
1429
+ z33.string(),
1430
+ z33.object({
1431
+ "@type": z33.literal("EducationalOccupationalCredential").default("EducationalOccupationalCredential"),
1432
+ credentialCategory: z33.string()
1433
+ // e.g. "bachelor degree", "high school"
1434
+ })
1435
+ ]).optional(),
1436
+ experienceInPlaceOfEducation: z33.boolean().optional(),
1437
+ qualifications: z33.string().optional(),
1438
+ responsibilities: z33.string().optional(),
1439
+ skills: z33.union([z33.string(), z33.array(z33.string())]).optional(),
1440
+ industry: z33.string().optional(),
1441
+ occupationalCategory: z33.string().optional(),
1442
+ // O*NET-SOC codes
1443
+ workHours: z33.string().optional(),
1444
+ url: z33.url().optional(),
1445
+ sameAs: z33.url().optional()
1446
+ });
1447
+ var createJobPosting = makeFactory(JobPostingSchema);
1448
+
1449
+ // src/types/intangibles/QAPage.ts
1450
+ import { z as z34 } from "zod";
1451
+ var AnswerSchema = z34.object({
1452
+ "@type": z34.literal("Answer").default("Answer"),
1453
+ text: z34.string(),
1454
+ dateCreated: z34.string().optional(),
1455
+ // ISO 8601
1456
+ upvoteCount: z34.number().int().nonnegative().optional(),
1457
+ url: z34.url().optional(),
1458
+ author: PersonOrOrgRef.optional()
1459
+ });
1460
+ var QuestionSchema = z34.object({
1461
+ "@type": z34.literal("Question").default("Question"),
1462
+ name: z34.string(),
1463
+ // The question text (also used as headline)
1464
+ text: z34.string().optional(),
1465
+ // Extended question text
1466
+ acceptedAnswer: z34.union([AnswerSchema, z34.array(AnswerSchema)]).optional(),
1467
+ suggestedAnswer: z34.union([AnswerSchema, z34.array(AnswerSchema)]).optional(),
1468
+ answerCount: z34.number().int().nonnegative().optional(),
1469
+ upvoteCount: z34.number().int().nonnegative().optional(),
1470
+ author: PersonOrOrgRef.optional(),
1471
+ dateCreated: z34.string().optional(),
1472
+ datePublished: z34.string().optional(),
1473
+ url: z34.url().optional()
1474
+ });
1475
+ var FAQPageSchema = WebPageSchema.extend({
1476
+ "@type": z34.literal("FAQPage").default("FAQPage"),
1477
+ mainEntity: z34.array(QuestionSchema)
1478
+ });
1479
+ var QAPageSchema = WebPageSchema.extend({
1480
+ "@type": z34.literal("QAPage").default("QAPage"),
1481
+ mainEntity: QuestionSchema
1482
+ });
1483
+ var QuizSchema = CreativeWorkSchema.extend({
1484
+ "@type": z34.literal("Quiz").default("Quiz"),
1485
+ name: z34.string().optional(),
1486
+ educationalLevel: z34.string().optional(),
1487
+ about: z34.lazy(
1488
+ () => z34.object({ "@type": z34.string() }).catchall(z34.unknown())
1489
+ ).optional(),
1490
+ hasPart: z34.array(QuestionSchema).optional(),
1491
+ educationalAlignment: z34.object({
1492
+ "@type": z34.literal("AlignmentObject").default("AlignmentObject"),
1493
+ alignmentType: z34.string().optional(),
1494
+ targetName: z34.string().optional(),
1495
+ targetUrl: z34.url().optional()
1496
+ }).optional()
1497
+ });
1498
+ var createFAQPage = makeFactory(FAQPageSchema);
1499
+ var createQAPage = makeFactory(QAPageSchema);
1500
+ var createQuiz = makeFactory(QuizSchema);
1501
+ var createQuestion = makeFactory(QuestionSchema);
1502
+
1503
+ // src/types/intangibles/DiscussionForum.ts
1504
+ import { z as z35 } from "zod";
1505
+ var DiscussionForumPostingSchema = CreativeWorkSchema.extend({
1506
+ "@type": z35.literal("DiscussionForumPosting").default("DiscussionForumPosting"),
1507
+ // Required by Google:
1508
+ headline: z35.string(),
1509
+ author: PersonOrOrgRef,
1510
+ // Recommended:
1511
+ text: z35.string().optional(),
1512
+ datePublished: z35.string().optional(),
1513
+ // ISO 8601
1514
+ url: z35.url().optional(),
1515
+ comment: z35.array(z35.object({
1516
+ "@type": z35.literal("Comment").default("Comment"),
1517
+ text: z35.string(),
1518
+ author: PersonOrOrgRef.optional(),
1519
+ datePublished: z35.string().optional(),
1520
+ upvoteCount: z35.number().int().nonnegative().optional(),
1521
+ downvoteCount: z35.number().int().nonnegative().optional(),
1522
+ url: z35.url().optional()
1523
+ })).optional(),
1524
+ commentCount: z35.number().int().nonnegative().optional(),
1525
+ upvoteCount: z35.number().int().nonnegative().optional(),
1526
+ downvoteCount: z35.number().int().nonnegative().optional(),
1527
+ image: ImageOrUrl.optional(),
1528
+ // For reposts:
1529
+ sharedContent: z35.lazy(
1530
+ () => z35.object({ "@type": z35.string() }).catchall(z35.unknown())
1531
+ ).optional(),
1532
+ interactionStatistic: z35.array(z35.object({
1533
+ "@type": z35.literal("InteractionCounter").default("InteractionCounter"),
1534
+ interactionType: z35.string(),
1535
+ userInteractionCount: z35.number().int().nonnegative()
1536
+ })).optional()
1537
+ });
1538
+ var createDiscussionForumPosting = makeFactory(DiscussionForumPostingSchema);
1539
+
1540
+ // src/types/intangibles/ItemList.ts
1541
+ import { z as z36 } from "zod";
1542
+ var ListItemSchema = z36.object({
1543
+ "@type": z36.literal("ListItem").default("ListItem"),
1544
+ position: z36.number().int().positive(),
1545
+ url: z36.url().optional(),
1546
+ name: z36.string().optional(),
1547
+ // item: the actual entity being listed (loose ref to any schema node)
1548
+ item: z36.lazy(
1549
+ () => z36.object({ "@type": z36.string() }).catchall(z36.unknown())
1550
+ ).optional()
1551
+ });
1552
+ var ItemListSchema = z36.object({
1553
+ "@type": z36.literal("ItemList").default("ItemList"),
1554
+ name: z36.string().optional(),
1555
+ description: z36.string().optional(),
1556
+ url: z36.url().optional(),
1557
+ itemListOrder: z36.enum(["Ascending", "Descending", "Unordered"]).transform((v) => `https://schema.org/ItemListOrder${v}`).optional(),
1558
+ numberOfItems: z36.number().int().nonnegative().optional(),
1559
+ itemListElement: z36.array(
1560
+ z36.union([
1561
+ ListItemSchema,
1562
+ z36.object({ "@type": z36.string() }).catchall(z36.unknown())
1563
+ ])
1564
+ )
1565
+ });
1566
+ var createItemList = makeFactory(ItemListSchema);
1567
+
1568
+ // src/types/intangibles/ProfilePage.ts
1569
+ import { z as z37 } from "zod";
1570
+ var ProfilePageSchema = WebPageSchema.extend({
1571
+ "@type": z37.literal("ProfilePage").default("ProfilePage"),
1572
+ // mainEntity: the person or org this profile is about (loose ref to avoid circular imports)
1573
+ mainEntity: z37.lazy(
1574
+ () => z37.object({ "@type": z37.string() }).catchall(z37.unknown())
1575
+ ).optional(),
1576
+ // hasPart: content published by/about this profile subject
1577
+ hasPart: z37.array(
1578
+ z37.lazy(() => z37.object({ "@type": z37.string() }).catchall(z37.unknown()))
1579
+ ).optional(),
1580
+ dateCreated: z37.string().optional(),
1581
+ dateModified: z37.string().optional()
1582
+ });
1583
+ var createProfilePage = makeFactory(ProfilePageSchema);
1584
+
1585
+ // src/types/lodging/VacationRental.ts
1586
+ import { z as z38 } from "zod";
1587
+ var BedTypeEnum = z38.enum([
1588
+ "Single bed",
1589
+ "Double bed",
1590
+ "Bunk bed",
1591
+ "Queen bed",
1592
+ "King bed",
1593
+ "Sofa bed",
1594
+ "Cot",
1595
+ "Waterbed",
1596
+ "Toddler bed"
1597
+ ]);
1598
+ var BedDetailsSchema = z38.object({
1599
+ "@type": z38.literal("BedDetails").default("BedDetails"),
1600
+ numberOfBeds: z38.number().int().positive().optional(),
1601
+ typeOfBed: z38.union([BedTypeEnum, z38.string()]).optional()
1602
+ });
1603
+ var LocationFeatureSpecificationSchema = z38.object({
1604
+ "@type": z38.literal("LocationFeatureSpecification").default("LocationFeatureSpecification"),
1605
+ name: z38.string(),
1606
+ value: z38.union([z38.boolean(), z38.string(), z38.number()]).optional()
1607
+ });
1608
+ var AccommodationSchema = z38.object({
1609
+ "@type": z38.literal("Accommodation").default("Accommodation"),
1610
+ name: z38.string().optional(),
1611
+ occupancy: z38.object({
1612
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1613
+ value: z38.number().int().positive().optional(),
1614
+ maxValue: z38.number().int().positive().optional(),
1615
+ minValue: z38.number().int().positive().optional()
1616
+ }).optional(),
1617
+ numberOfRooms: z38.number().int().nonnegative().optional(),
1618
+ numberOfBedrooms: z38.number().int().nonnegative().optional(),
1619
+ numberOfBathroomsTotal: z38.number().int().nonnegative().optional(),
1620
+ floorSize: z38.object({
1621
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1622
+ value: z38.number(),
1623
+ /** "MTK" = sq metres, "FTK" = sq ft */
1624
+ unitCode: z38.string().optional()
1625
+ }).optional(),
1626
+ bed: z38.union([BedDetailsSchema, z38.array(BedDetailsSchema)]).optional(),
1627
+ amenityFeature: z38.union([
1628
+ LocationFeatureSpecificationSchema,
1629
+ z38.array(LocationFeatureSpecificationSchema)
1630
+ ]).optional(),
1631
+ petsAllowed: z38.union([z38.boolean(), z38.string()]).optional(),
1632
+ url: z38.url().optional()
1633
+ });
1634
+ var VacationRentalSchema = LocalBusinessSchema.extend({
1635
+ "@type": z38.literal("VacationRental").default("VacationRental"),
1636
+ // Required by Google:
1637
+ name: z38.string(),
1638
+ // Recommended by Google:
1639
+ description: z38.string().optional(),
1640
+ image: z38.union([ImageOrUrl, z38.array(ImageOrUrl)]).optional(),
1641
+ // Lodging-specific:
1642
+ petsAllowed: z38.union([z38.boolean(), z38.string()]).optional(),
1643
+ checkinTime: z38.string().optional(),
1644
+ // e.g. "15:00"
1645
+ checkoutTime: z38.string().optional(),
1646
+ // e.g. "11:00"
1647
+ numberOfRooms: z38.union([
1648
+ z38.number(),
1649
+ z38.object({
1650
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1651
+ value: z38.number()
1652
+ })
1653
+ ]).optional(),
1654
+ occupancy: z38.object({
1655
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1656
+ maxValue: z38.number(),
1657
+ minValue: z38.number().optional()
1658
+ }).optional(),
1659
+ starRating: z38.object({
1660
+ "@type": z38.literal("Rating").default("Rating"),
1661
+ ratingValue: z38.number().min(0).max(5)
1662
+ }).optional(),
1663
+ offers: z38.union([OfferSchema, z38.array(OfferSchema)]).optional(),
1664
+ leaseLength: z38.union([z38.string(), z38.object({
1665
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1666
+ value: z38.number(),
1667
+ unitCode: z38.string().optional()
1668
+ })]).optional(),
1669
+ floorSize: z38.object({
1670
+ "@type": z38.literal("QuantitativeValue").default("QuantitativeValue"),
1671
+ value: z38.number(),
1672
+ unitCode: z38.string().optional()
1673
+ // e.g. "MTK" (square meters), "FTK" (sq ft)
1674
+ }).optional(),
1675
+ numberOfBathroomsTotal: z38.number().int().nonnegative().optional(),
1676
+ numberOfBedrooms: z38.number().int().nonnegative().optional(),
1677
+ tourBookingPage: z38.url().optional(),
1678
+ /** Accommodation unit(s) within the rental property — required by Google */
1679
+ containsPlace: z38.union([AccommodationSchema, z38.array(AccommodationSchema)]).optional()
1680
+ });
1681
+ var createVacationRental = makeFactory(VacationRentalSchema);
1682
+
1683
+ // src/core/registry.ts
1684
+ var REGISTRY = {
1685
+ // Things
1686
+ Person: PersonSchema,
1687
+ Organization: OrganizationSchema,
1688
+ Product: ProductSchema,
1689
+ ProductGroup: ProductGroupSchema,
1690
+ Event: EventSchema,
1691
+ Place: PlaceSchema,
1692
+ LocalBusiness: LocalBusinessSchema,
1693
+ Movie: MovieSchema,
1694
+ // Creative Works
1695
+ Book: BookSchema,
1696
+ Article: ArticleSchema,
1697
+ NewsArticle: NewsArticleSchema,
1698
+ BlogPosting: BlogPostingSchema,
1699
+ WebPage: WebPageSchema,
1700
+ WebSite: WebSiteSchema,
1701
+ Dataset: DatasetSchema,
1702
+ Recipe: RecipeSchema,
1703
+ Course: CourseSchema,
1704
+ SoftwareApplication: SoftwareApplicationSchema,
1705
+ MathSolver: MathSolverSchema,
1706
+ // Intangibles
1707
+ Language: LanguageSchema,
1708
+ PronounceableText: PronounceableTextSchema,
1709
+ JobPosting: JobPostingSchema,
1710
+ FAQPage: FAQPageSchema,
1711
+ QAPage: QAPageSchema,
1712
+ Quiz: QuizSchema,
1713
+ Question: QuestionSchema,
1714
+ DiscussionForumPosting: DiscussionForumPostingSchema,
1715
+ ItemList: ItemListSchema,
1716
+ ProfilePage: ProfilePageSchema,
1717
+ // Lodging
1718
+ VacationRental: VacationRentalSchema,
1719
+ // Shared types (useful in unified factory)
1720
+ ImageObject: ImageObjectSchema,
1721
+ Offer: OfferSchema,
1722
+ Review: ReviewSchema,
1723
+ VideoObject: VideoObjectSchema
1724
+ };
1725
+ function schema(type, data) {
1726
+ const zodSchema = REGISTRY[type];
1727
+ const parsed = zodSchema.parse(data);
1728
+ return new SchemaNode(zodSchema, parsed);
1729
+ }
1730
+
1731
+ // src/core/graph.ts
1732
+ var SchemaGraph = class {
1733
+ constructor() {
1734
+ this.items = [];
1735
+ }
1736
+ /**
1737
+ * Add a SchemaNode or plain object to the graph.
1738
+ * Returns `this` for fluent chaining.
1739
+ */
1740
+ add(node) {
1741
+ if (node instanceof SchemaNode) {
1742
+ this.items.push(node.toObject());
1743
+ } else {
1744
+ this.items.push(node);
1745
+ }
1746
+ return this;
1747
+ }
1748
+ /** Returns the raw array of graph items (without @context). */
1749
+ toArray() {
1750
+ return [...this.items];
1751
+ }
1752
+ /** Returns the full JSON-LD object with @context and @graph. */
1753
+ toJsonLd() {
1754
+ return {
1755
+ "@context": "https://schema.org",
1756
+ "@graph": this.items
1757
+ };
1758
+ }
1759
+ /** Returns a <script type="application/ld+json"> tag string. */
1760
+ toScript() {
1761
+ return `<script type="application/ld+json">
1762
+ ${JSON.stringify(this.toJsonLd(), null, 2)}
1763
+ </script>`;
1764
+ }
1765
+ /** Returns prettified JSON string. */
1766
+ toString() {
1767
+ return JSON.stringify(this.toJsonLd(), null, 2);
1768
+ }
1769
+ };
1770
+ function createGraph(nodes) {
1771
+ const graph = new SchemaGraph();
1772
+ for (const node of nodes) {
1773
+ graph.add(node);
1774
+ }
1775
+ return graph;
1776
+ }
1777
+
1778
+ // src/helpers/breadcrumb.ts
1779
+ import { z as z39 } from "zod";
1780
+ var BreadcrumbListSchema = z39.object({
1781
+ "@type": z39.literal("BreadcrumbList").default("BreadcrumbList"),
1782
+ itemListElement: z39.array(
1783
+ z39.object({
1784
+ "@type": z39.literal("ListItem").default("ListItem"),
1785
+ position: z39.number().int().positive(),
1786
+ name: z39.string(),
1787
+ item: z39.url().optional()
1788
+ })
1789
+ )
1790
+ });
1791
+ function createBreadcrumbList(items) {
1792
+ const data = BreadcrumbListSchema.parse({
1793
+ itemListElement: items.map((item, index) => ({
1794
+ "@type": "ListItem",
1795
+ position: index + 1,
1796
+ name: item.name,
1797
+ ...item.url ? { item: item.url } : {}
1798
+ }))
1799
+ });
1800
+ return new SchemaNode(BreadcrumbListSchema, data);
1801
+ }
1802
+
1803
+ // src/helpers/faq.ts
1804
+ function createFAQPage2(items) {
1805
+ const data = FAQPageSchema.parse({
1806
+ mainEntity: items.map(({ question, answer }) => ({
1807
+ "@type": "Question",
1808
+ name: question,
1809
+ acceptedAnswer: {
1810
+ "@type": "Answer",
1811
+ text: answer
1812
+ }
1813
+ }))
1814
+ });
1815
+ return new SchemaNode(FAQPageSchema, data);
1816
+ }
1817
+
1818
+ // src/helpers/itemlist.ts
1819
+ function createCarousel(items) {
1820
+ const elements = items.map((item, index) => {
1821
+ if (item instanceof SchemaNode) {
1822
+ return {
1823
+ "@type": "ListItem",
1824
+ position: index + 1,
1825
+ item: item.toObject()
1826
+ };
1827
+ }
1828
+ return {
1829
+ "@type": "ListItem",
1830
+ position: index + 1,
1831
+ url: item.url,
1832
+ ...item.name ? { name: item.name } : {}
1833
+ };
1834
+ });
1835
+ const data = ItemListSchema.parse({ itemListElement: elements });
1836
+ return new SchemaNode(ItemListSchema, data);
1837
+ }
1838
+
1839
+ // src/helpers/paywalled.ts
1840
+ function createPaywalledArticle(data, options) {
1841
+ return createArticle({
1842
+ ...data,
1843
+ isAccessibleForFree: false,
1844
+ hasPart: [{
1845
+ "@type": "WebPageElement",
1846
+ isAccessibleForFree: false,
1847
+ cssSelector: options.cssSelector
1848
+ }]
1849
+ });
1850
+ }
1851
+ function createPaywalledWebPage(data, options) {
1852
+ return createWebPage({
1853
+ ...data,
1854
+ isAccessibleForFree: false,
1855
+ hasPart: [{
1856
+ "@type": "WebPageElement",
1857
+ isAccessibleForFree: false,
1858
+ cssSelector: options.cssSelector
1859
+ }]
1860
+ });
1861
+ }
1862
+ export {
1863
+ AccommodationSchema,
1864
+ AggregateOfferSchema,
1865
+ AggregateRatingSchema,
1866
+ AnswerSchema,
1867
+ ApplicationCategory,
1868
+ ArticleSchema,
1869
+ BedDetailsSchema,
1870
+ BedTypeEnum,
1871
+ BlogPostingSchema,
1872
+ BookEditionSchema,
1873
+ BookFormatType,
1874
+ BookSchema,
1875
+ BorrowActionSchema,
1876
+ BroadcastEventSchema,
1877
+ CertificationSchema,
1878
+ ClipSchema,
1879
+ ContactPointSchema,
1880
+ CourseInstanceSchema,
1881
+ CourseSchema,
1882
+ CreativeWorkSchema,
1883
+ DatasetSchema,
1884
+ DayOfWeek,
1885
+ DefinedRegionSchema,
1886
+ DiscussionForumPostingSchema,
1887
+ EmployerAggregateRatingSchema,
1888
+ EmploymentType,
1889
+ EventAttendanceMode,
1890
+ EventSchema,
1891
+ EventStatusType,
1892
+ FAQPageSchema,
1893
+ GeoCoordinatesSchema,
1894
+ HowToSectionSchema,
1895
+ HowToStepSchema,
1896
+ ImageObjectSchema,
1897
+ ImageOrUrl,
1898
+ ItemAvailability,
1899
+ ItemListSchema,
1900
+ JobPostingSchema,
1901
+ LanguageSchema,
1902
+ ListItemSchema,
1903
+ LocalBusinessSchema,
1904
+ MathSolverSchema,
1905
+ MerchantReturnPolicySchema,
1906
+ MonetaryAmountSchema,
1907
+ MovieSchema,
1908
+ NewsArticleSchema,
1909
+ NutritionInformationSchema,
1910
+ OfferSchema,
1911
+ OfferShippingDetailsSchema,
1912
+ OpeningHoursSpecificationSchema,
1913
+ OrganizationSchema,
1914
+ PersonOrOrgRef,
1915
+ PersonSchema,
1916
+ PlaceSchema,
1917
+ PostalAddressSchema,
1918
+ PriceSpecificationSchema,
1919
+ ProductGroupSchema,
1920
+ ProductSchema,
1921
+ ProfilePageSchema,
1922
+ PronounceableTextSchema,
1923
+ PropertyValueSchema,
1924
+ QAPageSchema,
1925
+ QuestionSchema,
1926
+ QuizSchema,
1927
+ RatingSchema,
1928
+ ReadActionSchema,
1929
+ RecipeSchema,
1930
+ ReviewSchema,
1931
+ SchemaGraph,
1932
+ SchemaNode,
1933
+ ShippingDeliveryTimeSchema,
1934
+ SoftwareApplicationSchema,
1935
+ SolveMathActionSchema,
1936
+ ThingSchema,
1937
+ ThreeDModelSchema,
1938
+ VacationRentalSchema,
1939
+ VideoObjectSchema,
1940
+ WebPageSchema,
1941
+ WebSiteSchema,
1942
+ createArticle,
1943
+ createBlogPosting,
1944
+ createBook,
1945
+ createBreadcrumbList,
1946
+ createCarousel,
1947
+ createCorporation,
1948
+ createCourse,
1949
+ createDataset,
1950
+ createDiscussionForumPosting,
1951
+ createEvent,
1952
+ createFAQPage2 as createFAQPage,
1953
+ createGraph,
1954
+ createHotel,
1955
+ createImageObject,
1956
+ createItemList,
1957
+ createJobPosting,
1958
+ createLanguage,
1959
+ createLocalBusiness,
1960
+ createMathSolver,
1961
+ createMobileApplication,
1962
+ createMovie,
1963
+ createNGO,
1964
+ createNewsArticle,
1965
+ createOffer,
1966
+ createOnlineBusiness,
1967
+ createOnlineStore,
1968
+ createOrganization,
1969
+ createPaywalledArticle,
1970
+ createPaywalledWebPage,
1971
+ createPerson,
1972
+ createPlace,
1973
+ createProduct,
1974
+ createProductGroup,
1975
+ createProfilePage,
1976
+ createPronounceableText,
1977
+ createQAPage,
1978
+ createQuestion,
1979
+ createQuiz,
1980
+ createRecipe,
1981
+ createRestaurant,
1982
+ createSoftwareApplication,
1983
+ createVacationRental,
1984
+ createVideoObject,
1985
+ createWebApplication,
1986
+ createWebPage,
1987
+ createWebSite,
1988
+ extendThing,
1989
+ makeFactory,
1990
+ schema
1991
+ };