schemaorg-kit 1.1.0 → 1.2.0

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/README.md CHANGED
@@ -27,7 +27,11 @@ Requires **Node.js ≥ 18** and **Zod ≥ 4.3**.
27
27
  ## Quick Start
28
28
 
29
29
  ```typescript
30
- import { createProduct, createOffer, createBreadcrumbList } from "schemaorg-kit";
30
+ import {
31
+ createProduct,
32
+ createOffer,
33
+ createBreadcrumbList,
34
+ } from "schemaorg-kit";
31
35
 
32
36
  const product = createProduct({
33
37
  name: "Running Shoes",
@@ -50,14 +54,14 @@ const jsonLd = product.toJsonLd(); // includes @context
50
54
 
51
55
  Every node returned by a factory exposes these methods:
52
56
 
53
- | Method | Returns | Description |
54
- |--------|---------|-------------|
55
- | `.toObject()` | `T` | Raw validated object — use this when nesting inside another schema |
56
- | `.toJsonLd()` | `Record<string, unknown>` | Object with `@context: "https://schema.org"` added |
57
- | `.toScript()` | `string` | Full `<script type="application/ld+json">` tag, ready for HTML |
58
- | `.toString()` | `string` | Pretty-printed JSON string |
59
- | `.validate()` | `this` | Throws a `ZodError` if data is invalid (chainable) |
60
- | `.safeParse()` | Zod result | Returns `{ success, data, error }` without throwing |
57
+ | Method | Returns | Description |
58
+ | -------------- | ------------------------- | ------------------------------------------------------------------ |
59
+ | `.toObject()` | `T` | Raw validated object — use this when nesting inside another schema |
60
+ | `.toJsonLd()` | `Record<string, unknown>` | Object with `@context: "https://schema.org"` added |
61
+ | `.toScript()` | `string` | Full `<script type="application/ld+json">` tag, ready for HTML |
62
+ | `.toString()` | `string` | Pretty-printed JSON string |
63
+ | `.validate()` | `this` | Throws a `ZodError` if data is invalid (chainable) |
64
+ | `.safeParse()` | Zod result | Returns `{ success, data, error }` without throwing |
61
65
 
62
66
  ## Composing Schemas
63
67
 
@@ -70,7 +74,7 @@ const author = createPerson({ name: "Jane Doe", url: "https://janedoe.com" });
70
74
 
71
75
  const article = createArticle({
72
76
  headline: "Hello World",
73
- author: author.toObject(), // <-- nest with .toObject()
77
+ author: author.toObject(), // <-- nest with .toObject()
74
78
  publisher: createOrganization({
75
79
  name: "Acme Blog",
76
80
  url: "https://acmeblog.com",
@@ -83,25 +87,42 @@ console.log(article.toScript());
83
87
 
84
88
  ## `@graph` Support
85
89
 
86
- Use `createGraph` to output multiple schema nodes in a single `<script>` tag with `@id` cross-references:
90
+ Use `createGraph` to output multiple schema nodes in a single `<script>` tag. Use `SchemaIds` for consistent `@id` cross-references:
87
91
 
88
92
  ```typescript
89
- import { createGraph, createWebPage, createArticle, createPerson } from "schemaorg-kit";
93
+ import {
94
+ SchemaIds,
95
+ createGraph,
96
+ createOrganization,
97
+ createWebSite,
98
+ createWebPage,
99
+ } from "schemaorg-kit";
100
+
101
+ const ids = new SchemaIds("https://example.com");
90
102
 
91
103
  const graph = createGraph([
92
- createWebPage({ "@id": "https://example.com/post#webpage", url: "https://example.com/post" }),
93
- createArticle({
94
- "@id": "https://example.com/post#article",
95
- headline: "Hello World",
96
- isPartOf: { "@id": "https://example.com/post#webpage" },
97
- author: { "@id": "https://example.com/about#person" },
104
+ createOrganization({
105
+ "@id": ids.organization(),
106
+ name: "Acme Corp",
107
+ url: "https://example.com",
108
+ }),
109
+ createWebSite({
110
+ "@id": ids.website(),
111
+ name: "Acme",
112
+ url: "https://example.com",
113
+ publisher: ids.ref("organization"), // { "@id": "https://example.com/#organization" }
114
+ }),
115
+ createWebPage({
116
+ "@id": ids.webpage(),
117
+ url: "https://example.com",
98
118
  }),
99
- createPerson({ "@id": "https://example.com/about#person", name: "Jane Doe" }),
100
119
  ]);
101
120
 
102
121
  console.log(graph.toScript());
103
122
  ```
104
123
 
124
+ `SchemaIds` provides well-known methods (`organization()`, `website()`, `webpage()`, `person()`, etc.), `custom()` for arbitrary fragments, `forPath()` for page-scoped IDs, and `ref()` for cross-reference objects.
125
+
105
126
  ## Unified Factory
106
127
 
107
128
  As an alternative to named imports, use the `schema()` factory with any registered type name:
@@ -110,70 +131,70 @@ As an alternative to named imports, use the `schema()` factory with any register
110
131
  import { schema } from "schemaorg-kit";
111
132
 
112
133
  const product = schema("Product", { name: "Shoes", sku: "SH-001" });
113
- const event = schema("Event", { name: "Conference", startDate: "2025-09-01" });
134
+ const event = schema("Event", { name: "Conference", startDate: "2025-09-01" });
114
135
  ```
115
136
 
116
137
  ## Supported Types
117
138
 
118
139
  ### Things
119
140
 
120
- | Factory | Schema.org Type |
121
- |---------|----------------|
122
- | `createPerson` | `Person` |
123
- | `createOrganization` | `Organization` |
124
- | `createCorporation` | `Corporation` |
125
- | `createNGO` | `NGO` |
126
- | `createOnlineStore` | `OnlineStore` |
141
+ | Factory | Schema.org Type |
142
+ | ---------------------- | ---------------- |
143
+ | `createPerson` | `Person` |
144
+ | `createOrganization` | `Organization` |
145
+ | `createCorporation` | `Corporation` |
146
+ | `createNGO` | `NGO` |
147
+ | `createOnlineStore` | `OnlineStore` |
127
148
  | `createOnlineBusiness` | `OnlineBusiness` |
128
- | `createProduct` | `Product` |
129
- | `createProductGroup` | `ProductGroup` |
130
- | `createEvent` | `Event` |
131
- | `createPlace` | `Place` |
132
- | `createLocalBusiness` | `LocalBusiness` |
133
- | `createRestaurant` | `Restaurant` |
134
- | `createHotel` | `Hotel` |
135
- | `createMovie` | `Movie` |
149
+ | `createProduct` | `Product` |
150
+ | `createProductGroup` | `ProductGroup` |
151
+ | `createEvent` | `Event` |
152
+ | `createPlace` | `Place` |
153
+ | `createLocalBusiness` | `LocalBusiness` |
154
+ | `createRestaurant` | `Restaurant` |
155
+ | `createHotel` | `Hotel` |
156
+ | `createMovie` | `Movie` |
136
157
 
137
158
  ### Creative Works
138
159
 
139
- | Factory | Schema.org Type |
140
- |---------|----------------|
141
- | `createBook` | `Book` (with ReadAction / BorrowAction) |
142
- | `createArticle` | `Article` |
143
- | `createNewsArticle` | `NewsArticle` |
144
- | `createBlogPosting` | `BlogPosting` |
145
- | `createWebPage` | `WebPage` |
146
- | `createWebSite` | `WebSite` |
147
- | `createDataset` | `Dataset` |
148
- | `createRecipe` | `Recipe` |
149
- | `createCourse` | `Course` |
150
- | `createSoftwareApplication` | `SoftwareApplication` |
151
- | `createMobileApplication` | `MobileApplication` |
152
- | `createWebApplication` | `WebApplication` |
153
- | `createMathSolver` | `MathSolver` |
154
- | `createClaimReview` | `ClaimReview` (Fact Check) |
160
+ | Factory | Schema.org Type |
161
+ | --------------------------- | --------------------------------------- |
162
+ | `createBook` | `Book` (with ReadAction / BorrowAction) |
163
+ | `createArticle` | `Article` |
164
+ | `createNewsArticle` | `NewsArticle` |
165
+ | `createBlogPosting` | `BlogPosting` |
166
+ | `createWebPage` | `WebPage` |
167
+ | `createWebSite` | `WebSite` |
168
+ | `createDataset` | `Dataset` |
169
+ | `createRecipe` | `Recipe` |
170
+ | `createCourse` | `Course` |
171
+ | `createSoftwareApplication` | `SoftwareApplication` |
172
+ | `createMobileApplication` | `MobileApplication` |
173
+ | `createWebApplication` | `WebApplication` |
174
+ | `createMathSolver` | `MathSolver` |
175
+ | `createClaimReview` | `ClaimReview` (Fact Check) |
155
176
 
156
177
  ### Intangibles & Other
157
178
 
158
- | Factory | Schema.org Type |
159
- |---------|----------------|
160
- | `createOffer` | `Offer` |
161
- | `createImageObject` | `ImageObject` |
162
- | `createVideoObject` | `VideoObject` |
163
- | `createJobPosting` | `JobPosting` |
179
+ | Factory | Schema.org Type |
180
+ | ------------------------------------------------ | ------------------------------ |
181
+ | `createOffer` | `Offer` |
182
+ | `createImageObject` | `ImageObject` |
183
+ | `createVideoObject` | `VideoObject` |
184
+ | `createJobPosting` | `JobPosting` |
164
185
  | `createQAPage` / `createQuiz` / `createQuestion` | `QAPage` / `Quiz` / `Question` |
165
- | `createDiscussionForumPosting` | `DiscussionForumPosting` |
166
- | `createProfilePage` | `ProfilePage` |
167
- | `createVacationRental` | `VacationRental` |
168
- | `createLanguage` | `Language` |
186
+ | `createDiscussionForumPosting` | `DiscussionForumPosting` |
187
+ | `createProfilePage` | `ProfilePage` |
188
+ | `createVacationRental` | `VacationRental` |
189
+ | `createLanguage` | `Language` |
169
190
 
170
191
  ### Helpers
171
192
 
172
- | Helper | What it does |
173
- |--------|-------------|
174
- | `createBreadcrumbList([...])` | Builds a `BreadcrumbList` from a plain array |
175
- | `createFAQPage([...])` | Builds a `FAQPage` from `{question, answer}` pairs |
176
- | `createCarousel([...])` | Wraps schema nodes in an `ItemList` carousel |
193
+ | Helper | What it does |
194
+ | ----------------------------- | ------------------------------------------------------------ |
195
+ | `createBreadcrumbList([...])` | Builds a `BreadcrumbList` from a plain array |
196
+ | `createFAQPage([...])` | Builds a `FAQPage` from `{question, answer}` pairs |
197
+ | `createCarousel([...])` | Wraps schema nodes in an `ItemList` carousel |
177
198
  | `createPaywalledArticle(...)` | Article with `isAccessibleForFree: false` paywalled sections |
178
199
 
179
200
  ## Common Patterns
@@ -201,7 +222,9 @@ const product = createProduct({
201
222
  availability: "InStock",
202
223
  shippingDetails: OfferShippingDetailsSchema.parse({
203
224
  shippingRate: { value: 0, currency: "USD" },
204
- shippingDestination: DefinedRegionSchema.parse({ addressCountry: "US" }),
225
+ shippingDestination: DefinedRegionSchema.parse({
226
+ addressCountry: "US",
227
+ }),
205
228
  deliveryTime: {
206
229
  handlingTime: { minValue: 0, maxValue: 1, unitCode: "DAY" },
207
230
  transitTime: { minValue: 3, maxValue: 5, unitCode: "DAY" },
@@ -218,8 +241,11 @@ const product = createProduct({
218
241
  import { createFAQPage } from "schemaorg-kit";
219
242
 
220
243
  const faq = createFAQPage([
221
- { question: "What is schemaorg-kit?", answer: "A type-safe schema.org builder." },
222
- { question: "Does it support @graph?", answer: "Yes, via createGraph()." },
244
+ {
245
+ question: "What is schemaorg-kit?",
246
+ answer: "A type-safe schema.org builder.",
247
+ },
248
+ { question: "Does it support @graph?", answer: "Yes, via createGraph()." },
223
249
  ]);
224
250
 
225
251
  document.head.innerHTML += faq.toScript();
@@ -231,9 +257,9 @@ document.head.innerHTML += faq.toScript();
231
257
  import { createBreadcrumbList } from "schemaorg-kit";
232
258
 
233
259
  const breadcrumb = createBreadcrumbList([
234
- { name: "Home", url: "https://example.com" },
260
+ { name: "Home", url: "https://example.com" },
235
261
  { name: "Products", url: "https://example.com/products" },
236
- { name: "Shoes" }, // last item — url is optional
262
+ { name: "Shoes" }, // last item — url is optional
237
263
  ]);
238
264
  ```
239
265
 
@@ -244,7 +270,7 @@ import { extendThing, makeFactory } from "schemaorg-kit";
244
270
  import { z } from "zod";
245
271
 
246
272
  const PodcastSchema = extendThing("PodcastSeries", {
247
- webFeed: z.string().url(),
273
+ webFeed: z.url(),
248
274
  numberOfEpisodes: z.number().int().optional(),
249
275
  });
250
276
 
@@ -263,7 +289,8 @@ src/
263
289
  ├── core/
264
290
  │ ├── base.ts # SchemaNode<T> class + makeFactory()
265
291
  │ ├── registry.ts # Unified schema() factory + REGISTRY
266
- └── graph.ts # SchemaGraph + createGraph()
292
+ ├── graph.ts # SchemaGraph + createGraph()
293
+ │ └── ids.ts # SchemaIds + SchemaId (cross-reference helpers)
267
294
  ├── types/
268
295
  │ ├── shared/ # Reusable building blocks
269
296
  │ │ ├── Offer.ts # Offer, AggregateOffer, MerchantReturnPolicy, UnitPriceSpecification, ItemCondition