@krantho/seo 0.0.0-stage → 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.
Files changed (243) hide show
  1. package/LICENSE +21 -0
  2. package/dist/archetypes/define-archetype.d.ts +23 -0
  3. package/dist/archetypes/define-archetype.d.ts.map +1 -0
  4. package/dist/archetypes/define-archetype.js +51 -0
  5. package/dist/archetypes/define-archetype.js.map +1 -0
  6. package/dist/archetypes/index.d.ts +4 -0
  7. package/dist/archetypes/index.d.ts.map +1 -0
  8. package/dist/archetypes/index.js +3 -0
  9. package/dist/archetypes/index.js.map +1 -0
  10. package/dist/archetypes/presets.d.ts +21 -0
  11. package/dist/archetypes/presets.d.ts.map +1 -0
  12. package/dist/archetypes/presets.js +42 -0
  13. package/dist/archetypes/presets.js.map +1 -0
  14. package/dist/archetypes/types.d.ts +20 -0
  15. package/dist/archetypes/types.d.ts.map +1 -0
  16. package/dist/archetypes/types.js +2 -0
  17. package/dist/archetypes/types.js.map +1 -0
  18. package/dist/catalog/auto-mappings.d.ts +39 -0
  19. package/dist/catalog/auto-mappings.d.ts.map +1 -0
  20. package/dist/catalog/auto-mappings.js +64 -0
  21. package/dist/catalog/auto-mappings.js.map +1 -0
  22. package/dist/catalog/index.d.ts +7 -0
  23. package/dist/catalog/index.d.ts.map +1 -0
  24. package/dist/catalog/index.js +4 -0
  25. package/dist/catalog/index.js.map +1 -0
  26. package/dist/catalog/properties.d.ts +9 -0
  27. package/dist/catalog/properties.d.ts.map +1 -0
  28. package/dist/catalog/properties.js +630 -0
  29. package/dist/catalog/properties.js.map +1 -0
  30. package/dist/catalog/property-atoms.d.ts +53 -0
  31. package/dist/catalog/property-atoms.d.ts.map +1 -0
  32. package/dist/catalog/property-atoms.js +170 -0
  33. package/dist/catalog/property-atoms.js.map +1 -0
  34. package/dist/catalog/types.d.ts +53 -0
  35. package/dist/catalog/types.d.ts.map +1 -0
  36. package/dist/catalog/types.js +423 -0
  37. package/dist/catalog/types.js.map +1 -0
  38. package/dist/create-seo.d.ts +70 -0
  39. package/dist/create-seo.d.ts.map +1 -0
  40. package/dist/create-seo.js +137 -0
  41. package/dist/create-seo.js.map +1 -0
  42. package/dist/decorators/breadcrumb.d.ts +12 -0
  43. package/dist/decorators/breadcrumb.d.ts.map +1 -0
  44. package/dist/decorators/breadcrumb.js +36 -0
  45. package/dist/decorators/breadcrumb.js.map +1 -0
  46. package/dist/decorators/index.d.ts +8 -0
  47. package/dist/decorators/index.d.ts.map +1 -0
  48. package/dist/decorators/index.js +13 -0
  49. package/dist/decorators/index.js.map +1 -0
  50. package/dist/decorators/nodes.d.ts +12 -0
  51. package/dist/decorators/nodes.d.ts.map +1 -0
  52. package/dist/decorators/nodes.js +29 -0
  53. package/dist/decorators/nodes.js.map +1 -0
  54. package/dist/decorators/page.d.ts +13 -0
  55. package/dist/decorators/page.d.ts.map +1 -0
  56. package/dist/decorators/page.js +68 -0
  57. package/dist/decorators/page.js.map +1 -0
  58. package/dist/decorators/registry.d.ts +11 -0
  59. package/dist/decorators/registry.d.ts.map +1 -0
  60. package/dist/decorators/registry.js +29 -0
  61. package/dist/decorators/registry.js.map +1 -0
  62. package/dist/decorators/sequence.d.ts +8 -0
  63. package/dist/decorators/sequence.d.ts.map +1 -0
  64. package/dist/decorators/sequence.js +22 -0
  65. package/dist/decorators/sequence.js.map +1 -0
  66. package/dist/decorators/types.d.ts +30 -0
  67. package/dist/decorators/types.d.ts.map +1 -0
  68. package/dist/decorators/types.js +2 -0
  69. package/dist/decorators/types.js.map +1 -0
  70. package/dist/define-seo.d.ts +21 -0
  71. package/dist/define-seo.d.ts.map +1 -0
  72. package/dist/define-seo.js +31 -0
  73. package/dist/define-seo.js.map +1 -0
  74. package/dist/graph/build-entity.d.ts +47 -0
  75. package/dist/graph/build-entity.d.ts.map +1 -0
  76. package/dist/graph/build-entity.js +69 -0
  77. package/dist/graph/build-entity.js.map +1 -0
  78. package/dist/graph/compose-from-config.d.ts +89 -0
  79. package/dist/graph/compose-from-config.d.ts.map +1 -0
  80. package/dist/graph/compose-from-config.js +189 -0
  81. package/dist/graph/compose-from-config.js.map +1 -0
  82. package/dist/graph/compose-graph.d.ts +40 -0
  83. package/dist/graph/compose-graph.d.ts.map +1 -0
  84. package/dist/graph/compose-graph.js +30 -0
  85. package/dist/graph/compose-graph.js.map +1 -0
  86. package/dist/graph/effective-config.d.ts +36 -0
  87. package/dist/graph/effective-config.d.ts.map +1 -0
  88. package/dist/graph/effective-config.js +84 -0
  89. package/dist/graph/effective-config.js.map +1 -0
  90. package/dist/graph/id-conventions.d.ts +47 -0
  91. package/dist/graph/id-conventions.d.ts.map +1 -0
  92. package/dist/graph/id-conventions.js +78 -0
  93. package/dist/graph/id-conventions.js.map +1 -0
  94. package/dist/graph/index.d.ts +9 -0
  95. package/dist/graph/index.d.ts.map +1 -0
  96. package/dist/graph/index.js +4 -0
  97. package/dist/graph/index.js.map +1 -0
  98. package/dist/graph/resolve-properties.d.ts +36 -0
  99. package/dist/graph/resolve-properties.d.ts.map +1 -0
  100. package/dist/graph/resolve-properties.js +141 -0
  101. package/dist/graph/resolve-properties.js.map +1 -0
  102. package/dist/graph/resolve-references.d.ts +14 -0
  103. package/dist/graph/resolve-references.d.ts.map +1 -0
  104. package/dist/graph/resolve-references.js +49 -0
  105. package/dist/graph/resolve-references.js.map +1 -0
  106. package/dist/graph/typed-value.d.ts +7 -0
  107. package/dist/graph/typed-value.d.ts.map +1 -0
  108. package/dist/graph/typed-value.js +43 -0
  109. package/dist/graph/typed-value.js.map +1 -0
  110. package/dist/graph/types.d.ts +34 -0
  111. package/dist/graph/types.d.ts.map +1 -0
  112. package/dist/graph/types.js +2 -0
  113. package/dist/graph/types.js.map +1 -0
  114. package/dist/graph/value-scope.d.ts +19 -0
  115. package/dist/graph/value-scope.d.ts.map +1 -0
  116. package/dist/graph/value-scope.js +30 -0
  117. package/dist/graph/value-scope.js.map +1 -0
  118. package/dist/index.d.ts +28 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +29 -0
  121. package/dist/index.js.map +1 -0
  122. package/dist/json-ld.d.ts +24 -0
  123. package/dist/json-ld.d.ts.map +1 -0
  124. package/dist/json-ld.js +24 -0
  125. package/dist/json-ld.js.map +1 -0
  126. package/dist/profiles/bing.d.ts +10 -0
  127. package/dist/profiles/bing.d.ts.map +1 -0
  128. package/dist/profiles/bing.js +13 -0
  129. package/dist/profiles/bing.js.map +1 -0
  130. package/dist/profiles/check.d.ts +11 -0
  131. package/dist/profiles/check.d.ts.map +1 -0
  132. package/dist/profiles/check.js +66 -0
  133. package/dist/profiles/check.js.map +1 -0
  134. package/dist/profiles/eligibility.d.ts +26 -0
  135. package/dist/profiles/eligibility.d.ts.map +1 -0
  136. package/dist/profiles/eligibility.js +49 -0
  137. package/dist/profiles/eligibility.js.map +1 -0
  138. package/dist/profiles/google.d.ts +4 -0
  139. package/dist/profiles/google.d.ts.map +1 -0
  140. package/dist/profiles/google.js +387 -0
  141. package/dist/profiles/google.js.map +1 -0
  142. package/dist/profiles/index.d.ts +10 -0
  143. package/dist/profiles/index.d.ts.map +1 -0
  144. package/dist/profiles/index.js +13 -0
  145. package/dist/profiles/index.js.map +1 -0
  146. package/dist/profiles/registry.d.ts +16 -0
  147. package/dist/profiles/registry.d.ts.map +1 -0
  148. package/dist/profiles/registry.js +66 -0
  149. package/dist/profiles/registry.js.map +1 -0
  150. package/dist/profiles/types.d.ts +29 -0
  151. package/dist/profiles/types.d.ts.map +1 -0
  152. package/dist/profiles/types.js +2 -0
  153. package/dist/profiles/types.js.map +1 -0
  154. package/dist/seo-graph.d.ts +39 -0
  155. package/dist/seo-graph.d.ts.map +1 -0
  156. package/dist/seo-graph.js +34 -0
  157. package/dist/seo-graph.js.map +1 -0
  158. package/dist/types/built-in/content.d.ts +12 -0
  159. package/dist/types/built-in/content.d.ts.map +1 -0
  160. package/dist/types/built-in/content.js +79 -0
  161. package/dist/types/built-in/content.js.map +1 -0
  162. package/dist/types/built-in/events.d.ts +23 -0
  163. package/dist/types/built-in/events.d.ts.map +1 -0
  164. package/dist/types/built-in/events.js +93 -0
  165. package/dist/types/built-in/events.js.map +1 -0
  166. package/dist/types/built-in/index.d.ts +4 -0
  167. package/dist/types/built-in/index.d.ts.map +1 -0
  168. package/dist/types/built-in/index.js +26 -0
  169. package/dist/types/built-in/index.js.map +1 -0
  170. package/dist/types/built-in/media.d.ts +21 -0
  171. package/dist/types/built-in/media.d.ts.map +1 -0
  172. package/dist/types/built-in/media.js +104 -0
  173. package/dist/types/built-in/media.js.map +1 -0
  174. package/dist/types/built-in/site.d.ts +14 -0
  175. package/dist/types/built-in/site.d.ts.map +1 -0
  176. package/dist/types/built-in/site.js +35 -0
  177. package/dist/types/built-in/site.js.map +1 -0
  178. package/dist/types/context.d.ts +26 -0
  179. package/dist/types/context.d.ts.map +1 -0
  180. package/dist/types/context.js +44 -0
  181. package/dist/types/context.js.map +1 -0
  182. package/dist/types/definition.d.ts +58 -0
  183. package/dist/types/definition.d.ts.map +1 -0
  184. package/dist/types/definition.js +2 -0
  185. package/dist/types/definition.js.map +1 -0
  186. package/dist/types/index.d.ts +4 -0
  187. package/dist/types/index.d.ts.map +1 -0
  188. package/dist/types/index.js +3 -0
  189. package/dist/types/index.js.map +1 -0
  190. package/dist/types/registry.d.ts +14 -0
  191. package/dist/types/registry.d.ts.map +1 -0
  192. package/dist/types/registry.js +37 -0
  193. package/dist/types/registry.js.map +1 -0
  194. package/dist/types/values.d.ts +23 -0
  195. package/dist/types/values.d.ts.map +1 -0
  196. package/dist/types/values.js +52 -0
  197. package/dist/types/values.js.map +1 -0
  198. package/dist/validate/check-terms.d.ts +15 -0
  199. package/dist/validate/check-terms.d.ts.map +1 -0
  200. package/dist/validate/check-terms.js +42 -0
  201. package/dist/validate/check-terms.js.map +1 -0
  202. package/dist/validate/check-value.d.ts +19 -0
  203. package/dist/validate/check-value.d.ts.map +1 -0
  204. package/dist/validate/check-value.js +77 -0
  205. package/dist/validate/check-value.js.map +1 -0
  206. package/dist/validate/graph-nodes.d.ts +22 -0
  207. package/dist/validate/graph-nodes.d.ts.map +1 -0
  208. package/dist/validate/graph-nodes.js +50 -0
  209. package/dist/validate/graph-nodes.js.map +1 -0
  210. package/dist/validate/index.d.ts +4 -0
  211. package/dist/validate/index.d.ts.map +1 -0
  212. package/dist/validate/index.js +2 -0
  213. package/dist/validate/index.js.map +1 -0
  214. package/dist/validate/types.d.ts +22 -0
  215. package/dist/validate/types.d.ts.map +1 -0
  216. package/dist/validate/types.js +2 -0
  217. package/dist/validate/types.js.map +1 -0
  218. package/dist/validate/validate-graph.d.ts +18 -0
  219. package/dist/validate/validate-graph.d.ts.map +1 -0
  220. package/dist/validate/validate-graph.js +109 -0
  221. package/dist/validate/validate-graph.js.map +1 -0
  222. package/dist/vocabulary/datatypes.d.ts +7 -0
  223. package/dist/vocabulary/datatypes.d.ts.map +1 -0
  224. package/dist/vocabulary/datatypes.js +46 -0
  225. package/dist/vocabulary/datatypes.js.map +1 -0
  226. package/dist/vocabulary/index.d.ts +5 -0
  227. package/dist/vocabulary/index.d.ts.map +1 -0
  228. package/dist/vocabulary/index.js +4 -0
  229. package/dist/vocabulary/index.js.map +1 -0
  230. package/dist/vocabulary/schemaorg.generated.d.ts +4 -0
  231. package/dist/vocabulary/schemaorg.generated.d.ts.map +1 -0
  232. package/dist/vocabulary/schemaorg.generated.js +3038 -0
  233. package/dist/vocabulary/schemaorg.generated.js.map +1 -0
  234. package/dist/vocabulary/types.d.ts +38 -0
  235. package/dist/vocabulary/types.d.ts.map +1 -0
  236. package/dist/vocabulary/types.js +2 -0
  237. package/dist/vocabulary/types.js.map +1 -0
  238. package/dist/vocabulary/vocabulary.d.ts +28 -0
  239. package/dist/vocabulary/vocabulary.d.ts.map +1 -0
  240. package/dist/vocabulary/vocabulary.js +89 -0
  241. package/dist/vocabulary/vocabulary.js.map +1 -0
  242. package/package.json +41 -3
  243. package/README.md +0 -3
@@ -0,0 +1,423 @@
1
+ import { googleProfile } from '../profiles/google.js';
2
+ import { ruleFor } from '../profiles/registry.js';
3
+ import { lifecycleOf } from '../vocabulary/index.js';
4
+ export const CATEGORY_LABELS = {
5
+ business: 'Business & Organization',
6
+ content: 'Content & Media',
7
+ commerce: 'Products & Services',
8
+ people: 'People & Events',
9
+ navigation: 'Navigation & Structure',
10
+ reviews: 'Reviews & Ratings',
11
+ };
12
+ /**
13
+ * Curated catalog of Schema.org types relevant for SEO: types that make a page
14
+ * eligible for a search feature, or that sites commonly describe themselves
15
+ * and their pages with. Not the whole vocabulary — any current Schema.org
16
+ * type can be configured.
17
+ */
18
+ const CATALOG_ENTRIES = [
19
+ // ── Business & Organization ──
20
+ {
21
+ type: 'LocalBusiness',
22
+ label: 'Local Business',
23
+ description: 'A physical business or local service with an address.',
24
+ category: 'business',
25
+ siteLevel: true,
26
+ documentLevel: false,
27
+ },
28
+ {
29
+ type: 'ProfessionalService',
30
+ label: 'Professional Service',
31
+ description: 'Consulting, legal, accounting, or other professional services.',
32
+ category: 'business',
33
+ siteLevel: true,
34
+ documentLevel: false,
35
+ },
36
+ {
37
+ type: 'Organization',
38
+ label: 'Organization',
39
+ description: 'A company or organization without a physical storefront.',
40
+ category: 'business',
41
+ siteLevel: true,
42
+ documentLevel: false,
43
+ },
44
+ {
45
+ type: 'Restaurant',
46
+ label: 'Restaurant',
47
+ description: 'A food service establishment.',
48
+ category: 'business',
49
+ siteLevel: true,
50
+ documentLevel: false,
51
+ },
52
+ {
53
+ type: 'MedicalBusiness',
54
+ label: 'Medical Business',
55
+ description: 'Clinics, dentists, hospitals, and healthcare providers.',
56
+ category: 'business',
57
+ siteLevel: true,
58
+ documentLevel: false,
59
+ },
60
+ {
61
+ type: 'LegalService',
62
+ label: 'Legal Service',
63
+ description: 'Law firms and legal service providers.',
64
+ category: 'business',
65
+ siteLevel: true,
66
+ documentLevel: false,
67
+ },
68
+ {
69
+ type: 'FinancialService',
70
+ label: 'Financial Service',
71
+ description: 'Banks, insurance companies, and financial advisors.',
72
+ category: 'business',
73
+ siteLevel: true,
74
+ documentLevel: false,
75
+ },
76
+ {
77
+ type: 'RealEstateAgent',
78
+ label: 'Real Estate Agent',
79
+ description: 'Real estate agencies and property services.',
80
+ category: 'business',
81
+ siteLevel: true,
82
+ documentLevel: false,
83
+ },
84
+ {
85
+ type: 'AutoDealer',
86
+ label: 'Auto Dealer',
87
+ description: 'Car dealerships and vehicle sales.',
88
+ category: 'business',
89
+ siteLevel: true,
90
+ documentLevel: false,
91
+ },
92
+ {
93
+ type: 'HealthAndBeautyBusiness',
94
+ label: 'Health & Beauty',
95
+ description: 'Spas, salons, and beauty services.',
96
+ category: 'business',
97
+ siteLevel: true,
98
+ documentLevel: false,
99
+ },
100
+ {
101
+ type: 'FoodEstablishment',
102
+ label: 'Food Establishment',
103
+ description: 'Cafes, bars, bakeries, and food vendors.',
104
+ category: 'business',
105
+ siteLevel: true,
106
+ documentLevel: false,
107
+ },
108
+ {
109
+ type: 'EntertainmentBusiness',
110
+ label: 'Entertainment',
111
+ description: 'Cinemas, bowling alleys, and entertainment venues.',
112
+ category: 'business',
113
+ siteLevel: true,
114
+ documentLevel: false,
115
+ },
116
+ {
117
+ type: 'SportsActivityLocation',
118
+ label: 'Sports & Fitness',
119
+ description: 'Gyms, sports clubs, and fitness centers.',
120
+ category: 'business',
121
+ siteLevel: true,
122
+ documentLevel: false,
123
+ },
124
+ {
125
+ type: 'LodgingBusiness',
126
+ label: 'Lodging',
127
+ description: 'Hotels, hostels, and bed & breakfasts.',
128
+ category: 'business',
129
+ siteLevel: true,
130
+ documentLevel: false,
131
+ },
132
+ // ── Content ──
133
+ {
134
+ type: 'Article',
135
+ label: 'Article',
136
+ description: 'A news, blog, or editorial article.',
137
+ category: 'content',
138
+ siteLevel: false,
139
+ documentLevel: true,
140
+ },
141
+ {
142
+ type: 'BlogPosting',
143
+ label: 'Blog Post',
144
+ description: 'A blog post or journal entry.',
145
+ category: 'content',
146
+ siteLevel: false,
147
+ documentLevel: true,
148
+ },
149
+ {
150
+ type: 'NewsArticle',
151
+ label: 'News Article',
152
+ description: 'A news story with timely reporting.',
153
+ category: 'content',
154
+ siteLevel: false,
155
+ documentLevel: true,
156
+ },
157
+ {
158
+ type: 'HowTo',
159
+ label: 'How-To',
160
+ description: 'Step-by-step instructions for a task.',
161
+ category: 'content',
162
+ siteLevel: false,
163
+ documentLevel: true,
164
+ },
165
+ {
166
+ type: 'Recipe',
167
+ label: 'Recipe',
168
+ description: 'A food recipe with ingredients and steps.',
169
+ category: 'content',
170
+ siteLevel: false,
171
+ documentLevel: true,
172
+ },
173
+ {
174
+ type: 'Course',
175
+ label: 'Course',
176
+ description: 'An educational course or training program.',
177
+ category: 'content',
178
+ siteLevel: false,
179
+ documentLevel: true,
180
+ },
181
+ // ── Commerce & Services ──
182
+ {
183
+ type: 'Product',
184
+ label: 'Product',
185
+ description: 'A product available for purchase.',
186
+ category: 'commerce',
187
+ siteLevel: false,
188
+ documentLevel: true,
189
+ },
190
+ {
191
+ type: 'Service',
192
+ label: 'Service',
193
+ description: 'A service offered by a business.',
194
+ category: 'commerce',
195
+ siteLevel: false,
196
+ documentLevel: true,
197
+ },
198
+ {
199
+ type: 'Offer',
200
+ label: 'Offer',
201
+ description: 'A pricing offer for a product or service.',
202
+ category: 'commerce',
203
+ siteLevel: false,
204
+ documentLevel: true,
205
+ },
206
+ // ── People & Events ──
207
+ {
208
+ type: 'Person',
209
+ label: 'Person',
210
+ description: 'An individual — author, founder, team member.',
211
+ category: 'people',
212
+ siteLevel: true,
213
+ documentLevel: true,
214
+ },
215
+ {
216
+ type: 'Event',
217
+ label: 'Event',
218
+ description: 'A scheduled event — conference, workshop, webinar.',
219
+ category: 'people',
220
+ siteLevel: false,
221
+ documentLevel: true,
222
+ },
223
+ {
224
+ type: 'JobPosting',
225
+ label: 'Job Posting',
226
+ description: 'A job listing or career opportunity.',
227
+ category: 'people',
228
+ siteLevel: false,
229
+ documentLevel: true,
230
+ },
231
+ // ── Navigation & Structure ──
232
+ {
233
+ type: 'WebSite',
234
+ label: 'Website',
235
+ description: 'The website itself — gives search engines its name, on the home page.',
236
+ category: 'navigation',
237
+ siteLevel: true,
238
+ documentLevel: false,
239
+ },
240
+ {
241
+ type: 'WebPage',
242
+ label: 'Web Page',
243
+ description: 'A standard web page. Default type for all pages.',
244
+ category: 'navigation',
245
+ siteLevel: false,
246
+ documentLevel: true,
247
+ },
248
+ {
249
+ type: 'BreadcrumbList',
250
+ label: 'Breadcrumb',
251
+ description: 'Navigation trail showing page hierarchy.',
252
+ category: 'navigation',
253
+ siteLevel: false,
254
+ documentLevel: true,
255
+ },
256
+ {
257
+ type: 'FAQPage',
258
+ label: 'FAQ Page',
259
+ description: 'A page with question and answer pairs.',
260
+ category: 'navigation',
261
+ siteLevel: false,
262
+ documentLevel: true,
263
+ },
264
+ // ── Content (continued) ──
265
+ {
266
+ type: 'VideoObject',
267
+ label: 'Video',
268
+ description: 'A video with playback and metadata.',
269
+ category: 'content',
270
+ siteLevel: false,
271
+ documentLevel: true,
272
+ },
273
+ {
274
+ type: 'ImageObject',
275
+ label: 'Image',
276
+ description: 'An image with credits and metadata.',
277
+ category: 'content',
278
+ siteLevel: false,
279
+ documentLevel: true,
280
+ },
281
+ {
282
+ type: 'Dataset',
283
+ label: 'Dataset',
284
+ description: 'A structured dataset, for dataset search engines.',
285
+ category: 'content',
286
+ siteLevel: false,
287
+ documentLevel: true,
288
+ },
289
+ {
290
+ type: 'Movie',
291
+ label: 'Movie',
292
+ description: 'A movie with cast, crew, and release info.',
293
+ category: 'content',
294
+ siteLevel: false,
295
+ documentLevel: true,
296
+ },
297
+ {
298
+ type: 'DiscussionForumPosting',
299
+ label: 'Forum Post',
300
+ description: 'A posting in a discussion forum or community.',
301
+ category: 'content',
302
+ siteLevel: false,
303
+ documentLevel: true,
304
+ },
305
+ {
306
+ type: 'SpeakableSpecification',
307
+ label: 'Speakable',
308
+ description: 'Content sections suitable for voice assistant playback.',
309
+ category: 'content',
310
+ siteLevel: false,
311
+ documentLevel: true,
312
+ },
313
+ // ── Commerce & Services (continued) ──
314
+ {
315
+ type: 'SoftwareApplication',
316
+ label: 'Software App',
317
+ description: 'A software application or mobile app listing.',
318
+ category: 'commerce',
319
+ siteLevel: false,
320
+ documentLevel: true,
321
+ },
322
+ {
323
+ type: 'VacationRental',
324
+ label: 'Vacation Rental',
325
+ description: 'A vacation rental property listing.',
326
+ category: 'commerce',
327
+ siteLevel: false,
328
+ documentLevel: true,
329
+ },
330
+ {
331
+ type: 'EmployerAggregateRating',
332
+ label: 'Employer Rating',
333
+ description: 'Aggregate employee rating of an employer.',
334
+ category: 'commerce',
335
+ siteLevel: false,
336
+ documentLevel: true,
337
+ },
338
+ // ── Navigation & Structure (continued) ──
339
+ {
340
+ type: 'ItemList',
341
+ label: 'Item List',
342
+ description: 'An ordered or unordered list of items for carousel display.',
343
+ category: 'navigation',
344
+ siteLevel: false,
345
+ documentLevel: true,
346
+ },
347
+ {
348
+ type: 'ProfilePage',
349
+ label: 'Profile Page',
350
+ description: 'A page representing a person or organization profile.',
351
+ category: 'navigation',
352
+ siteLevel: false,
353
+ documentLevel: true,
354
+ },
355
+ {
356
+ type: 'QAPage',
357
+ label: 'Q&A Page',
358
+ description: 'A page with a single question and community answers.',
359
+ category: 'navigation',
360
+ siteLevel: false,
361
+ documentLevel: true,
362
+ },
363
+ // ── Reviews & Ratings ──
364
+ {
365
+ type: 'Review',
366
+ label: 'Review',
367
+ description: 'A single review of a product, service, or business.',
368
+ category: 'reviews',
369
+ siteLevel: false,
370
+ documentLevel: true,
371
+ },
372
+ {
373
+ type: 'AggregateRating',
374
+ label: 'Aggregate Rating',
375
+ description: 'Average rating from multiple reviews.',
376
+ category: 'reviews',
377
+ siteLevel: false,
378
+ documentLevel: true,
379
+ },
380
+ ];
381
+ /** The Google feature of an entry, from the Google profile's rule for its type */
382
+ function withFeature(entry) {
383
+ const rule = ruleFor(googleProfile, entry.type);
384
+ const lifecycle = lifecycleOf(entry.type);
385
+ return {
386
+ ...entry,
387
+ richResult: rule?.feature ?? null,
388
+ richResultStatus: rule?.status ?? 'none',
389
+ docsUrl: rule?.source ?? '',
390
+ ...(lifecycle ? { lifecycle } : {}),
391
+ };
392
+ }
393
+ /**
394
+ * The catalog. Each type's Google feature, status and documentation come from
395
+ * the Google profile, so the catalog cannot disagree with the rules findings
396
+ * are checked against.
397
+ */
398
+ export const SCHEMA_CATALOG = CATALOG_ENTRIES.map(withFeature);
399
+ // Pre-built indexes for O(1) lookups on the static catalog
400
+ const catalogByType = new Map(SCHEMA_CATALOG.map((t) => [t.type, t]));
401
+ const catalogByCategory = new Map(Object.keys(CATEGORY_LABELS).map((cat) => [
402
+ cat,
403
+ SCHEMA_CATALOG.filter((t) => t.category === cat),
404
+ ]));
405
+ const siteLevelTypes = SCHEMA_CATALOG.filter((t) => t.siteLevel);
406
+ const documentLevelTypes = SCHEMA_CATALOG.filter((t) => t.documentLevel);
407
+ /** Look up a catalog type by its Schema.org @type value */
408
+ export function getCatalogType(type) {
409
+ return catalogByType.get(type);
410
+ }
411
+ /** Get catalog types filtered by category */
412
+ export function getCatalogByCategory(category) {
413
+ return catalogByCategory.get(category) ?? [];
414
+ }
415
+ /** Get catalog types that can be used at site level */
416
+ export function getSiteLevelTypes() {
417
+ return siteLevelTypes;
418
+ }
419
+ /** Get catalog types that can be used at document level */
420
+ export function getDocumentLevelTypes() {
421
+ return documentLevelTypes;
422
+ }
423
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { SeoConfigData } from '@krantho/seo-shared';
2
+ import type { ComposeFromConfigOptions, ResolvedEntity } from './graph/compose-from-config.js';
3
+ import type { JsonLdGraph, SeoGraphConfig } from './graph/types.js';
4
+ import './profiles/index.js';
5
+ import type { FeatureEligibility } from './profiles/eligibility.js';
6
+ import type { Finding, GraphNode } from './validate/types.js';
7
+ type Scopes = Readonly<Record<string, SeoConfigData>>;
8
+ /** The configuration the SEO subsystem is created from: the `site` and `seo` sections of the loaded instance */
9
+ export interface SeoSettings {
10
+ readonly site: SeoGraphConfig & {
11
+ readonly sameAs: readonly string[];
12
+ };
13
+ readonly seo: {
14
+ readonly identity?: string | undefined;
15
+ readonly collections: Readonly<Record<string, readonly string[]>>;
16
+ readonly routes: Readonly<Record<string, readonly string[]>>;
17
+ readonly site?: SeoConfigData | undefined;
18
+ readonly richCollections: Scopes;
19
+ readonly richRoutes: Scopes;
20
+ readonly readers: readonly string[];
21
+ readonly definitions: {
22
+ readonly site: SeoConfigData | null;
23
+ readonly collections: Scopes;
24
+ readonly routes: Scopes;
25
+ };
26
+ };
27
+ }
28
+ /** A problem with the configuration itself, naming the setting that fixes it */
29
+ export interface ConfigurationFinding {
30
+ readonly severity: 'error' | 'warning' | 'info';
31
+ /** The configuration path to set or change, e.g. `site.logo` */
32
+ readonly setting: string;
33
+ readonly message: string;
34
+ }
35
+ /** Thrown when the configuration lacks what the structured data requires */
36
+ export declare class SeoConfigurationError extends Error {
37
+ readonly findings: readonly ConfigurationFinding[];
38
+ constructor(findings: readonly ConfigurationFinding[]);
39
+ }
40
+ /** The SEO subsystem of one site, created from its configuration */
41
+ export interface Seo {
42
+ /** The site's identity and address, as entities carry it */
43
+ readonly site: SeoGraphConfig;
44
+ /** The reader profiles graphs are checked against */
45
+ readonly readers: readonly string[];
46
+ /** What the configuration could do better — recommended values it lacks, pending terms it uses */
47
+ readonly findings: readonly ConfigurationFinding[];
48
+ /** Compose a page's graph with the site's identity */
49
+ compose(options: Omit<ComposeFromConfigOptions, 'siteConfig'>): JsonLdGraph;
50
+ /** Each entity of a page with its properties' values and sources, as the graph would carry them */
51
+ resolve(options: Omit<ComposeFromConfigOptions, 'siteConfig' | 'onFinding'>): ResolvedEntity[];
52
+ /** Validate a graph against the vocabulary and the active readers */
53
+ validate(graph: JsonLdGraph | GraphNode): Finding[];
54
+ /** The search features of the active readers a graph's entities can appear in, with what they lack */
55
+ features(graph: JsonLdGraph | GraphNode): FeatureEligibility[];
56
+ }
57
+ /**
58
+ * Create a site's SEO subsystem from its loaded configuration: the site's
59
+ * identity from `site`, the active readers from `seo.readers`, and the types
60
+ * and site entities from the `seo` section and its definition files.
61
+ *
62
+ * Fails fast on what is required, and only on that: an unknown reader, a type
63
+ * the vocabulary lacks or has superseded or retired, or a value of the site's
64
+ * identity an active reader requires throws a {@link SeoConfigurationError}
65
+ * naming each setting. A value a reader only recommends is a warning in
66
+ * `findings` and never stops anything.
67
+ */
68
+ export declare function createSeo(settings: SeoSettings): Seo;
69
+ export {};
70
+ //# sourceMappingURL=create-seo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-seo.d.ts","sourceRoot":"","sources":["../src/create-seo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { composeFromConfig, resolvePageEntities } from './graph/compose-from-config.js';
2
+ import { siteSettingFor } from './graph/resolve-properties.js';
3
+ import './profiles/index.js';
4
+ import { featureEligibility } from './profiles/eligibility.js';
5
+ import { getProfile, ruleFor } from './profiles/registry.js';
6
+ import { isEmpty } from './types/values.js';
7
+ import { validateGraph } from './validate/validate-graph.js';
8
+ import { getVocabularyType, lifecycleOf } from './vocabulary/index.js';
9
+ /** Thrown when the configuration lacks what the structured data requires */
10
+ export class SeoConfigurationError extends Error {
11
+ findings;
12
+ constructor(findings) {
13
+ const body = findings.map((f) => ` - ${f.setting}: ${f.message}`).join('\n');
14
+ super(`Invalid SEO configuration:\n${body}`);
15
+ this.name = 'SeoConfigurationError';
16
+ this.findings = findings;
17
+ }
18
+ }
19
+ /** Every type the configuration names, with the setting it is named in */
20
+ function configuredTypes(seo) {
21
+ const entities = (setting, scope) => (scope?.entities ?? []).map((entity) => [setting, entity['@type']]);
22
+ const scopes = (setting, record) => Object.entries(record).flatMap(([key, scope]) => entities(`${setting}.${key}`, scope));
23
+ const lists = (setting, record) => Object.entries(record).flatMap(([key, types]) => types.map((type) => [`${setting}.${key}`, type]));
24
+ const files = seo.definitions;
25
+ return [
26
+ ...(seo.identity ? [['seo.identity', seo.identity]] : []),
27
+ ...lists('seo.collections', seo.collections),
28
+ ...lists('seo.routes', seo.routes),
29
+ ...entities('seo.site', seo.site),
30
+ ...scopes('seo.richCollections', seo.richCollections),
31
+ ...scopes('seo.richRoutes', seo.richRoutes),
32
+ ...entities('seo.configDir (site)', files.site),
33
+ ...scopes('seo.configDir (collections)', files.collections),
34
+ ...scopes('seo.configDir (routes)', files.routes),
35
+ ];
36
+ }
37
+ /** A configured type must be a current Schema.org type; a pending one is noted */
38
+ function typeFindings(setting, type) {
39
+ if (!getVocabularyType(type)) {
40
+ return [{ severity: 'error', setting, message: `"${type}" is not a Schema.org type.` }];
41
+ }
42
+ const lifecycle = lifecycleOf(type);
43
+ if (lifecycle?.status === 'superseded') {
44
+ return [
45
+ {
46
+ severity: 'error',
47
+ setting,
48
+ message: `"${type}" is superseded by "${lifecycle.by}" in Schema.org.`,
49
+ },
50
+ ];
51
+ }
52
+ if (lifecycle?.status === 'retired') {
53
+ return [{ severity: 'error', setting, message: `"${type}" is retired from Schema.org.` }];
54
+ }
55
+ if (lifecycle?.status === 'pending') {
56
+ return [{ severity: 'info', setting, message: `"${type}" is a pending Schema.org term.` }];
57
+ }
58
+ return [];
59
+ }
60
+ /** The site entities the configuration defines, from every place it can define them */
61
+ function siteEntities(seo) {
62
+ const fromIdentity = seo.identity ? [{ '@type': seo.identity, properties: {} }] : [];
63
+ return [...(seo.definitions.site?.entities ?? []), ...(seo.site?.entities ?? fromIdentity)];
64
+ }
65
+ /** Values a reader needs from the site's identity that the configuration does not set */
66
+ function identityFindings(settings, readers) {
67
+ const findings = [];
68
+ for (const entity of siteEntities(settings.seo)) {
69
+ const type = entity['@type'];
70
+ for (const profile of readers) {
71
+ const rule = ruleFor(profile, type);
72
+ if (!rule || rule.status === 'none' || rule.status === 'retired')
73
+ continue;
74
+ const check = (properties, severity, verb) => {
75
+ for (const property of properties ?? []) {
76
+ const setting = siteSettingFor(type, property);
77
+ if (!setting || !isEmpty(entity.properties[property]) || !isEmpty(settings.site[setting]))
78
+ continue;
79
+ const message = `${profile.name} ${verb} "${property}" on ${type} (${rule.source}).`;
80
+ findings.push({ severity, setting: `site.${setting}`, message });
81
+ }
82
+ };
83
+ check(rule.required, 'error', 'requires');
84
+ check(rule.recommended, 'warning', 'recommends');
85
+ }
86
+ }
87
+ return findings;
88
+ }
89
+ function unique(findings) {
90
+ const seen = new Set();
91
+ return findings.filter((f) => {
92
+ const key = `${f.severity}|${f.setting}|${f.message}`;
93
+ if (seen.has(key))
94
+ return false;
95
+ seen.add(key);
96
+ return true;
97
+ });
98
+ }
99
+ /**
100
+ * Create a site's SEO subsystem from its loaded configuration: the site's
101
+ * identity from `site`, the active readers from `seo.readers`, and the types
102
+ * and site entities from the `seo` section and its definition files.
103
+ *
104
+ * Fails fast on what is required, and only on that: an unknown reader, a type
105
+ * the vocabulary lacks or has superseded or retired, or a value of the site's
106
+ * identity an active reader requires throws a {@link SeoConfigurationError}
107
+ * naming each setting. A value a reader only recommends is a warning in
108
+ * `findings` and never stops anything.
109
+ */
110
+ export function createSeo(settings) {
111
+ const unknownReaders = settings.seo.readers.filter((id) => !getProfile(id));
112
+ const readers = settings.seo.readers.flatMap((id) => getProfile(id) ?? []);
113
+ const findings = unique([
114
+ ...unknownReaders.map((id) => ({
115
+ severity: 'error',
116
+ setting: 'seo.readers',
117
+ message: `No reader profile "${id}" is registered.`,
118
+ })),
119
+ ...configuredTypes(settings.seo).flatMap(([setting, type]) => typeFindings(setting, type)),
120
+ ...identityFindings(settings, readers),
121
+ ]);
122
+ const errors = findings.filter((f) => f.severity === 'error');
123
+ if (errors.length > 0)
124
+ throw new SeoConfigurationError(errors);
125
+ const site = { ...settings.site };
126
+ const ids = readers.map((profile) => profile.id);
127
+ return {
128
+ site,
129
+ readers: ids,
130
+ findings,
131
+ compose: (options) => composeFromConfig({ ...options, siteConfig: site }),
132
+ resolve: (options) => resolvePageEntities({ ...options, siteConfig: site }),
133
+ validate: (graph) => validateGraph(graph, { profiles: ids }),
134
+ features: (graph) => featureEligibility(graph, ids),
135
+ };
136
+ }
137
+ //# sourceMappingURL=create-seo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-seo.js","sourceRoot":"","sources":["../src/create-seo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { TrailItem } from '@krantho/core';
2
+ import type { SchemaEntity } from '../graph/types.js';
3
+ import type { Decorator } from './types.js';
4
+ /** A trail as BreadcrumbList items; the last one may leave out its URL */
5
+ export declare function breadcrumbItems(trail: readonly TrailItem[]): SchemaEntity[];
6
+ /**
7
+ * The page's place in the hierarchy: a BreadcrumbList from the trail it
8
+ * renders — a configured BreadcrumbList is built from the same trail — linked
9
+ * from the page node.
10
+ */
11
+ export declare const breadcrumbDecorator: Decorator;
12
+ //# sourceMappingURL=breadcrumb.d.ts.map