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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 schemaorg-kit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # schemaorg-kit
2
+
3
+ [![npm](https://img.shields.io/npm/v/schemaorg-kit)](https://www.npmjs.com/package/schemaorg-kit)
4
+ [![CI](https://github.com/6f5/schemaorg-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/6f5/schemaorg-kit/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+
7
+ > Type-safe schema.org structured data for every Google rich result type — Zod validation, JSON-LD `@graph`, full TypeScript inference.
8
+
9
+ ## Features
10
+
11
+ - **35+ factory functions** covering all Google-supported rich result types
12
+ - **Zod v4 validation** with descriptive error messages at runtime
13
+ - **Full TypeScript autocomplete** — every field, every enum value
14
+ - **`@graph` support** for multi-entity pages with cross-references
15
+ - **Two APIs** — named factories (`createProduct`) or unified `schema("Product", {...})`
16
+ - **Dual ESM + CJS build** — works in Next.js, Remix, Astro, Node.js, and beyond
17
+ - **Zero dependencies** at runtime — Zod is a peer dependency you already have
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install schemaorg-kit zod
23
+ ```
24
+
25
+ Requires **Node.js ≥ 18** and **Zod ≥ 4.3**.
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { createProduct, createOffer, createBreadcrumbList } from "schemaorg-kit";
31
+
32
+ const product = createProduct({
33
+ name: "Running Shoes",
34
+ sku: "RS-001",
35
+ offers: createOffer({
36
+ price: 99.99,
37
+ priceCurrency: "USD",
38
+ availability: "InStock",
39
+ }).toObject(),
40
+ });
41
+
42
+ // Inject directly into HTML
43
+ document.head.innerHTML += product.toScript();
44
+
45
+ // Or get the plain object
46
+ const jsonLd = product.toJsonLd(); // includes @context
47
+ ```
48
+
49
+ ## Output Methods
50
+
51
+ Every node returned by a factory exposes these methods:
52
+
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 |
61
+
62
+ ## Composing Schemas
63
+
64
+ Call `.toObject()` when embedding one schema inside another:
65
+
66
+ ```typescript
67
+ import { createPerson, createOrganization, createArticle } from "schemaorg-kit";
68
+
69
+ const author = createPerson({ name: "Jane Doe", url: "https://janedoe.com" });
70
+
71
+ const article = createArticle({
72
+ headline: "Hello World",
73
+ author: author.toObject(), // <-- nest with .toObject()
74
+ publisher: createOrganization({
75
+ name: "Acme Blog",
76
+ url: "https://acmeblog.com",
77
+ logo: "https://acmeblog.com/logo.png",
78
+ }).toObject(),
79
+ });
80
+
81
+ console.log(article.toScript());
82
+ ```
83
+
84
+ ## `@graph` Support
85
+
86
+ Use `createGraph` to output multiple schema nodes in a single `<script>` tag with `@id` cross-references:
87
+
88
+ ```typescript
89
+ import { createGraph, createWebPage, createArticle, createPerson } from "schemaorg-kit";
90
+
91
+ 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" },
98
+ }),
99
+ createPerson({ "@id": "https://example.com/about#person", name: "Jane Doe" }),
100
+ ]);
101
+
102
+ console.log(graph.toScript());
103
+ ```
104
+
105
+ ## Unified Factory
106
+
107
+ As an alternative to named imports, use the `schema()` factory with any registered type name:
108
+
109
+ ```typescript
110
+ import { schema } from "schemaorg-kit";
111
+
112
+ const product = schema("Product", { name: "Shoes", sku: "SH-001" });
113
+ const event = schema("Event", { name: "Conference", startDate: "2025-09-01" });
114
+ ```
115
+
116
+ ## Supported Types
117
+
118
+ ### Things
119
+
120
+ | Factory | Schema.org Type |
121
+ |---------|----------------|
122
+ | `createPerson` | `Person` |
123
+ | `createOrganization` | `Organization` |
124
+ | `createCorporation` | `Corporation` |
125
+ | `createNGO` | `NGO` |
126
+ | `createOnlineStore` | `OnlineStore` |
127
+ | `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` |
136
+
137
+ ### Creative Works
138
+
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
+
155
+ ### Intangibles & Other
156
+
157
+ | Factory | Schema.org Type |
158
+ |---------|----------------|
159
+ | `createOffer` | `Offer` |
160
+ | `createImageObject` | `ImageObject` |
161
+ | `createVideoObject` | `VideoObject` |
162
+ | `createJobPosting` | `JobPosting` |
163
+ | `createQAPage` / `createQuiz` | `QAPage` / `Quiz` |
164
+ | `createDiscussionForumPosting` | `DiscussionForumPosting` |
165
+ | `createProfilePage` | `ProfilePage` |
166
+ | `createVacationRental` | `VacationRental` |
167
+ | `createLanguage` | `Language` |
168
+
169
+ ### Helpers
170
+
171
+ | Helper | What it does |
172
+ |--------|-------------|
173
+ | `createBreadcrumbList([...])` | Builds a `BreadcrumbList` from a plain array |
174
+ | `createFAQPage([...])` | Builds a `FAQPage` from `{question, answer}` pairs |
175
+ | `createCarousel([...])` | Wraps schema nodes in an `ItemList` carousel |
176
+ | `createPaywalledArticle(...)` | Article with `isAccessibleForFree: false` paywalled sections |
177
+
178
+ ## Common Patterns
179
+
180
+ ### Product with Price Range and Shipping
181
+
182
+ ```typescript
183
+ import {
184
+ createProduct,
185
+ AggregateOfferSchema,
186
+ OfferShippingDetailsSchema,
187
+ DefinedRegionSchema,
188
+ } from "schemaorg-kit";
189
+
190
+ const product = createProduct({
191
+ name: "Premium Headphones",
192
+ offers: AggregateOfferSchema.parse({
193
+ lowPrice: 79,
194
+ highPrice: 129,
195
+ priceCurrency: "USD",
196
+ offerCount: 4,
197
+ offers: {
198
+ price: 79,
199
+ priceCurrency: "USD",
200
+ availability: "InStock",
201
+ shippingDetails: OfferShippingDetailsSchema.parse({
202
+ shippingRate: { value: 0, currency: "USD" },
203
+ shippingDestination: DefinedRegionSchema.parse({ addressCountry: "US" }),
204
+ deliveryTime: {
205
+ handlingTime: { minValue: 0, maxValue: 1, unitCode: "DAY" },
206
+ transitTime: { minValue: 3, maxValue: 5, unitCode: "DAY" },
207
+ },
208
+ }),
209
+ },
210
+ }),
211
+ });
212
+ ```
213
+
214
+ ### FAQ Page
215
+
216
+ ```typescript
217
+ import { createFAQPage } from "schemaorg-kit";
218
+
219
+ const faq = createFAQPage([
220
+ { question: "What is schemaorg-kit?", answer: "A type-safe schema.org builder." },
221
+ { question: "Does it support @graph?", answer: "Yes, via createGraph()." },
222
+ ]);
223
+
224
+ document.head.innerHTML += faq.toScript();
225
+ ```
226
+
227
+ ### BreadcrumbList
228
+
229
+ ```typescript
230
+ import { createBreadcrumbList } from "schemaorg-kit";
231
+
232
+ const breadcrumb = createBreadcrumbList([
233
+ { name: "Home", url: "https://example.com" },
234
+ { name: "Products", url: "https://example.com/products" },
235
+ { name: "Shoes" }, // last item — url is optional
236
+ ]);
237
+ ```
238
+
239
+ ### Extending with Custom Types
240
+
241
+ ```typescript
242
+ import { extendThing, makeFactory } from "schemaorg-kit";
243
+ import { z } from "zod";
244
+
245
+ const PodcastSchema = extendThing("PodcastSeries", {
246
+ webFeed: z.string().url(),
247
+ numberOfEpisodes: z.number().int().optional(),
248
+ });
249
+
250
+ const createPodcast = makeFactory(PodcastSchema);
251
+
252
+ const podcast = createPodcast({
253
+ name: "My Show",
254
+ webFeed: "https://example.com/feed.rss",
255
+ });
256
+ ```
257
+
258
+ ## Project Structure
259
+
260
+ ```
261
+ src/
262
+ ├── core/
263
+ │ ├── base.ts # SchemaNode<T> class + makeFactory()
264
+ │ ├── registry.ts # Unified schema() factory + REGISTRY
265
+ │ └── graph.ts # SchemaGraph + createGraph()
266
+ ├── types/
267
+ │ ├── shared/ # Reusable building blocks
268
+ │ │ ├── Offer.ts # Offer, AggregateOffer, MerchantReturnPolicy
269
+ │ │ ├── ShippingDetails.ts # OfferShippingDetails, DefinedRegion, ShippingDeliveryTime
270
+ │ │ ├── Rating.ts # Rating, AggregateRating, Review, EmployerAggregateRating
271
+ │ │ ├── VideoObject.ts # VideoObject, Clip, BroadcastEvent
272
+ │ │ └── ...
273
+ │ ├── things/ # Person, Organization, Product, Place, Event, ...
274
+ │ ├── creative-works/ # Article, WebPage, WebSite, Recipe, Book, ...
275
+ │ ├── intangibles/ # JobPosting, FAQPage, ItemList, ProfilePage, ...
276
+ │ └── lodging/ # VacationRental, Accommodation
277
+ ├── helpers/ # Ergonomic wrappers (breadcrumb, faq, carousel, paywalled)
278
+ └── index.ts # Public API
279
+ ```
280
+
281
+ ## Links
282
+
283
+ - **Docs**: https://6f5.github.io/schemaorg-kit/
284
+ - **npm**: https://www.npmjs.com/package/schemaorg-kit
285
+ - **Issues**: https://github.com/6f5/schemaorg-kit/issues
286
+
287
+ ## License
288
+
289
+ MIT