@puzzle-ui/seo 0.0.0-stage → 0.5.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.
Files changed (220) hide show
  1. package/README.md +755 -2
  2. package/dist/LICENSE +21 -0
  3. package/dist/context/config.cjs +82 -0
  4. package/dist/context/config.cjs.map +1 -0
  5. package/dist/context/config.d.cts +6 -0
  6. package/dist/context/config.d.ts +6 -0
  7. package/dist/context/config.js +80 -0
  8. package/dist/context/config.js.map +1 -0
  9. package/dist/context/index.cjs +6 -0
  10. package/dist/context/index.d.cts +4 -0
  11. package/dist/context/index.d.ts +4 -0
  12. package/dist/context/index.js +3 -0
  13. package/dist/context/types.d.cts +46 -0
  14. package/dist/context/types.d.ts +46 -0
  15. package/dist/core/graph.cjs +464 -0
  16. package/dist/core/graph.cjs.map +1 -0
  17. package/dist/core/graph.d.cts +62 -0
  18. package/dist/core/graph.d.ts +62 -0
  19. package/dist/core/graph.js +456 -0
  20. package/dist/core/graph.js.map +1 -0
  21. package/dist/core/index.cjs +11 -0
  22. package/dist/core/index.d.cts +3 -0
  23. package/dist/core/index.d.ts +3 -0
  24. package/dist/core/index.js +1 -0
  25. package/dist/core/types.d.cts +92 -0
  26. package/dist/core/types.d.ts +92 -0
  27. package/dist/index.cjs +96 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +48 -0
  30. package/dist/index.d.ts +38 -0
  31. package/dist/index.js +19 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/metadata/index.cjs +4 -0
  34. package/dist/metadata/index.d.cts +3 -0
  35. package/dist/metadata/index.d.ts +3 -0
  36. package/dist/metadata/index.js +1 -0
  37. package/dist/metadata/resolve.cjs +122 -0
  38. package/dist/metadata/resolve.cjs.map +1 -0
  39. package/dist/metadata/resolve.d.cts +4 -0
  40. package/dist/metadata/resolve.d.ts +4 -0
  41. package/dist/metadata/resolve.js +121 -0
  42. package/dist/metadata/resolve.js.map +1 -0
  43. package/dist/metadata/types.d.cts +82 -0
  44. package/dist/metadata/types.d.ts +82 -0
  45. package/dist/next/index.cjs +13 -0
  46. package/dist/next/index.cjs.map +1 -0
  47. package/dist/next/index.d.cts +15 -0
  48. package/dist/next/index.d.ts +14 -0
  49. package/dist/next/index.js +12 -0
  50. package/dist/next/index.js.map +1 -0
  51. package/dist/react/context.cjs +30 -0
  52. package/dist/react/context.cjs.map +1 -0
  53. package/dist/react/context.d.cts +14 -0
  54. package/dist/react/context.d.ts +14 -0
  55. package/dist/react/context.js +27 -0
  56. package/dist/react/context.js.map +1 -0
  57. package/dist/react/index.cjs +48 -0
  58. package/dist/react/index.d.cts +6 -0
  59. package/dist/react/index.d.ts +6 -0
  60. package/dist/react/index.js +5 -0
  61. package/dist/react/metadata.cjs +100 -0
  62. package/dist/react/metadata.cjs.map +1 -0
  63. package/dist/react/metadata.d.cts +18 -0
  64. package/dist/react/metadata.d.ts +18 -0
  65. package/dist/react/metadata.js +99 -0
  66. package/dist/react/metadata.js.map +1 -0
  67. package/dist/react/provider.cjs +42 -0
  68. package/dist/react/provider.cjs.map +1 -0
  69. package/dist/react/provider.d.cts +3 -0
  70. package/dist/react/provider.d.ts +3 -0
  71. package/dist/react/provider.js +42 -0
  72. package/dist/react/provider.js.map +1 -0
  73. package/dist/react/schema-components.cjs +294 -0
  74. package/dist/react/schema-components.cjs.map +1 -0
  75. package/dist/react/schema-components.d.cts +84 -0
  76. package/dist/react/schema-components.d.ts +80 -0
  77. package/dist/react/schema-components.js +254 -0
  78. package/dist/react/schema-components.js.map +1 -0
  79. package/dist/react/types.d.cts +81 -0
  80. package/dist/react/types.d.ts +80 -0
  81. package/dist/react-router/index.cjs +13 -0
  82. package/dist/react-router/index.cjs.map +1 -0
  83. package/dist/react-router/index.d.cts +21 -0
  84. package/dist/react-router/index.d.ts +20 -0
  85. package/dist/react-router/index.js +12 -0
  86. package/dist/react-router/index.js.map +1 -0
  87. package/dist/robots/generate.cjs +88 -0
  88. package/dist/robots/generate.cjs.map +1 -0
  89. package/dist/robots/generate.d.cts +4 -0
  90. package/dist/robots/generate.d.ts +4 -0
  91. package/dist/robots/generate.js +86 -0
  92. package/dist/robots/generate.js.map +1 -0
  93. package/dist/robots/index.cjs +5 -0
  94. package/dist/robots/index.d.cts +3 -0
  95. package/dist/robots/index.d.ts +3 -0
  96. package/dist/robots/index.js +1 -0
  97. package/dist/robots/types.d.cts +27 -0
  98. package/dist/robots/types.d.ts +27 -0
  99. package/dist/schema/create-registry.cjs +12 -0
  100. package/dist/schema/create-registry.cjs.map +1 -0
  101. package/dist/schema/create-registry.d.cts +2 -0
  102. package/dist/schema/create-registry.d.ts +2 -0
  103. package/dist/schema/create-registry.js +12 -0
  104. package/dist/schema/create-registry.js.map +1 -0
  105. package/dist/schema/generated/index.d.cts +2 -0
  106. package/dist/schema/generated/schemaorg.cjs +36386 -0
  107. package/dist/schema/generated/schemaorg.cjs.map +1 -0
  108. package/dist/schema/generated/schemaorg.d.cts +945 -0
  109. package/dist/schema/generated/schemaorg.d.ts +945 -0
  110. package/dist/schema/generated/schemaorg.js +36384 -0
  111. package/dist/schema/generated/schemaorg.js.map +1 -0
  112. package/dist/schema/index.cjs +11 -0
  113. package/dist/schema/index.d.cts +7 -0
  114. package/dist/schema/index.d.ts +6 -0
  115. package/dist/schema/index.js +5 -0
  116. package/dist/schema/registry.cjs +194 -0
  117. package/dist/schema/registry.cjs.map +1 -0
  118. package/dist/schema/registry.d.cts +2 -0
  119. package/dist/schema/registry.d.ts +2 -0
  120. package/dist/schema/registry.js +194 -0
  121. package/dist/schema/registry.js.map +1 -0
  122. package/dist/schema/types.d.cts +79 -0
  123. package/dist/schema/types.d.ts +79 -0
  124. package/dist/schema/validate.cjs +131 -0
  125. package/dist/schema/validate.cjs.map +1 -0
  126. package/dist/schema/validate.d.cts +16 -0
  127. package/dist/schema/validate.d.ts +16 -0
  128. package/dist/schema/validate.js +131 -0
  129. package/dist/schema/validate.js.map +1 -0
  130. package/dist/server/handlers.cjs +96 -0
  131. package/dist/server/handlers.cjs.map +1 -0
  132. package/dist/server/handlers.d.cts +3 -0
  133. package/dist/server/handlers.d.ts +3 -0
  134. package/dist/server/handlers.js +95 -0
  135. package/dist/server/handlers.js.map +1 -0
  136. package/dist/server/index.cjs +6 -0
  137. package/dist/server/index.d.cts +4 -0
  138. package/dist/server/index.d.ts +4 -0
  139. package/dist/server/index.js +3 -0
  140. package/dist/server/routes.cjs +17 -0
  141. package/dist/server/routes.cjs.map +1 -0
  142. package/dist/server/routes.d.cts +2 -0
  143. package/dist/server/routes.d.ts +2 -0
  144. package/dist/server/routes.js +17 -0
  145. package/dist/server/routes.js.map +1 -0
  146. package/dist/server/types.d.cts +61 -0
  147. package/dist/server/types.d.ts +61 -0
  148. package/dist/sitemap/generate.cjs +147 -0
  149. package/dist/sitemap/generate.cjs.map +1 -0
  150. package/dist/sitemap/generate.d.cts +3 -0
  151. package/dist/sitemap/generate.d.ts +3 -0
  152. package/dist/sitemap/generate.js +146 -0
  153. package/dist/sitemap/generate.js.map +1 -0
  154. package/dist/sitemap/index.cjs +11 -0
  155. package/dist/sitemap/index.d.cts +4 -0
  156. package/dist/sitemap/index.d.ts +4 -0
  157. package/dist/sitemap/index.js +3 -0
  158. package/dist/sitemap/types.d.cts +82 -0
  159. package/dist/sitemap/types.d.ts +82 -0
  160. package/dist/sitemap/xml.cjs +215 -0
  161. package/dist/sitemap/xml.cjs.map +1 -0
  162. package/dist/sitemap/xml.d.cts +16 -0
  163. package/dist/sitemap/xml.d.ts +16 -0
  164. package/dist/sitemap/xml.js +210 -0
  165. package/dist/sitemap/xml.js.map +1 -0
  166. package/dist/tanstack/index.cjs +13 -0
  167. package/dist/tanstack/index.cjs.map +1 -0
  168. package/dist/tanstack/index.d.cts +19 -0
  169. package/dist/tanstack/index.d.ts +18 -0
  170. package/dist/tanstack/index.js +12 -0
  171. package/dist/tanstack/index.js.map +1 -0
  172. package/dist/testing/diagnostics.cjs +27 -0
  173. package/dist/testing/diagnostics.cjs.map +1 -0
  174. package/dist/testing/diagnostics.d.cts +3 -0
  175. package/dist/testing/diagnostics.d.ts +3 -0
  176. package/dist/testing/diagnostics.js +27 -0
  177. package/dist/testing/diagnostics.js.map +1 -0
  178. package/dist/testing/fixture.cjs +80 -0
  179. package/dist/testing/fixture.cjs.map +1 -0
  180. package/dist/testing/fixture.d.cts +4 -0
  181. package/dist/testing/fixture.d.ts +4 -0
  182. package/dist/testing/fixture.js +78 -0
  183. package/dist/testing/fixture.js.map +1 -0
  184. package/dist/testing/index.cjs +9 -0
  185. package/dist/testing/index.d.cts +5 -0
  186. package/dist/testing/index.d.ts +5 -0
  187. package/dist/testing/index.js +4 -0
  188. package/dist/testing/inspect.cjs +63 -0
  189. package/dist/testing/inspect.cjs.map +1 -0
  190. package/dist/testing/inspect.d.cts +5 -0
  191. package/dist/testing/inspect.d.ts +5 -0
  192. package/dist/testing/inspect.js +63 -0
  193. package/dist/testing/inspect.js.map +1 -0
  194. package/dist/testing/types.d.cts +40 -0
  195. package/dist/testing/types.d.ts +40 -0
  196. package/dist/urls/index.cjs +8 -0
  197. package/dist/urls/index.d.cts +3 -0
  198. package/dist/urls/index.d.ts +3 -0
  199. package/dist/urls/index.js +1 -0
  200. package/dist/urls/normalize.cjs +65 -0
  201. package/dist/urls/normalize.cjs.map +1 -0
  202. package/dist/urls/normalize.d.cts +14 -0
  203. package/dist/urls/normalize.d.ts +14 -0
  204. package/dist/urls/normalize.js +60 -0
  205. package/dist/urls/normalize.js.map +1 -0
  206. package/dist/urls/types.d.cts +22 -0
  207. package/dist/urls/types.d.ts +22 -0
  208. package/dist/validation/index.cjs +5 -0
  209. package/dist/validation/index.d.cts +3 -0
  210. package/dist/validation/index.d.ts +3 -0
  211. package/dist/validation/index.js +1 -0
  212. package/dist/validation/types.d.cts +75 -0
  213. package/dist/validation/types.d.ts +75 -0
  214. package/dist/validation/validate.cjs +452 -0
  215. package/dist/validation/validate.cjs.map +1 -0
  216. package/dist/validation/validate.d.cts +7 -0
  217. package/dist/validation/validate.d.ts +6 -0
  218. package/dist/validation/validate.js +450 -0
  219. package/dist/validation/validate.js.map +1 -0
  220. package/package.json +203 -4
@@ -0,0 +1,254 @@
1
+ "use client";
2
+ import { createSeoGraphBuilder, stringifySeoGraph } from "../core/graph.js";
3
+ import { createDefaultSchemaRegistry } from "../schema/create-registry.js";
4
+ import { validateSeo } from "../validation/validate.js";
5
+ import { Fragment, createContext, createElement, useContext, useEffect } from "react";
6
+ // src/react/schema-components.tsx
7
+ const defaultRegistry = createDefaultSchemaRegistry();
8
+ const SchemaContext = createContext(null);
9
+ const useSchemaCollector = () => {
10
+ const collector = useContext(SchemaContext);
11
+ if (!collector) throw new Error("Puzzle SEO schema components must be rendered inside SeoProvider.");
12
+ return collector;
13
+ };
14
+ /**
15
+ * Throws when a strict validation report contains errors.
16
+ */
17
+ const assertSeoValidationReport = (report) => {
18
+ if (report.mode !== "strict" || report.valid) return;
19
+ const errors = report.issues.filter((issue) => issue.severity === "error");
20
+ const messages = errors.map((issue) => `[${issue.source}:${issue.code}] ${issue.message}`);
21
+ const scope = errors.length > 0 && errors.every((issue) => issue.source === "schema" || issue.source === "registry") ? "schema validation" : "validation";
22
+ throw new Error(`Puzzle SEO ${scope} failed:\n${messages.join("\n")}`);
23
+ };
24
+ const SchemaGraphOutput = ({ collector }) => {
25
+ const graph = collector.builder.build();
26
+ const graphErrors = collector.builder.getIssues().filter((issue) => issue.severity === "error");
27
+ const report = collector.validation !== false ? validateSeo({
28
+ graph,
29
+ metadata: collector.metadata
30
+ }, {
31
+ ...collector.validation,
32
+ registry: collector.validation.registry ?? collector.registry,
33
+ baseUrl: collector.validation.baseUrl ?? collector.config.siteUrl
34
+ }) : void 0;
35
+ useEffect(() => {
36
+ if (report && collector.onValidation) collector.onValidation(report);
37
+ }, [report, collector.onValidation]);
38
+ if (graphErrors.length > 0) throw new Error(`Puzzle SEO graph validation failed:\n${graphErrors.map((issue) => issue.message).join("\n")}`);
39
+ if (report) assertSeoValidationReport(report);
40
+ if (graph["@graph"].length === 0) return null;
41
+ const json = stringifySeoGraph(graph, {
42
+ pretty: false,
43
+ safe: true,
44
+ scriptSafe: true,
45
+ validate: true
46
+ });
47
+ return createElement("script", {
48
+ id: collector.scriptId,
49
+ type: "application/ld+json",
50
+ nonce: collector.nonce,
51
+ dangerouslySetInnerHTML: { __html: json }
52
+ });
53
+ };
54
+ /**
55
+ * Legacy options are identified by `strict`, the only property that
56
+ * SeoValidationOptions does not share; `mode` always wins when present.
57
+ */
58
+ const isLegacyValidation = (validation) => "strict" in validation && !("mode" in validation);
59
+ const normalizeValidation = (validation) => {
60
+ if (validation === false) return false;
61
+ if (!isLegacyValidation(validation)) return validation;
62
+ const { strict, ...options } = validation;
63
+ return {
64
+ ...options,
65
+ mode: strict ? "strict" : "warn"
66
+ };
67
+ };
68
+ /**
69
+ * Central SEO provider.
70
+ *
71
+ * Creates an isolated graph builder for every render.
72
+ * All descendant schema components register into this graph.
73
+ *
74
+ * The final JSON-LD script is rendered after the children.
75
+ */
76
+ const SeoProvider = ({ config, children, scriptId = "puzzle-seo-jsonld", nonce, graphOptions, schemaRegistry, metadata, validation = {}, onValidation }) => {
77
+ const options = {
78
+ ...graphOptions,
79
+ baseUrl: graphOptions?.baseUrl ?? config.siteUrl
80
+ };
81
+ const normalizedValidation = normalizeValidation(validation);
82
+ const collector = {
83
+ config,
84
+ builder: createSeoGraphBuilder(options),
85
+ registry: normalizedValidation !== false ? normalizedValidation.registry ?? schemaRegistry ?? defaultRegistry : schemaRegistry ?? defaultRegistry,
86
+ metadata,
87
+ validation: normalizedValidation,
88
+ onValidation,
89
+ nonce,
90
+ scriptId
91
+ };
92
+ return createElement(SchemaContext.Provider, { value: collector }, createElement(Fragment, null, children, createElement(SchemaGraphOutput, { collector })));
93
+ };
94
+ /**
95
+ * Registers a Schema.org node.
96
+ *
97
+ * All properties are preserved. The graph engine is responsible
98
+ * for normalization, references, deduplication and ID generation.
99
+ */
100
+ const registerSchema = (collector, type, props) => {
101
+ const { id, data, ...properties } = props;
102
+ const node = {
103
+ ...data,
104
+ ...properties,
105
+ "@type": type
106
+ };
107
+ if (id !== void 0) node["@id"] = id;
108
+ collector.builder.add(node);
109
+ return null;
110
+ };
111
+ /**
112
+ * Generic Schema.org component.
113
+ *
114
+ * Supports generated Schema.org definitions and custom types.
115
+ */
116
+ const Schema = ({ type, id, data, properties }) => {
117
+ const collector = useSchemaCollector();
118
+ const node = {
119
+ ...data,
120
+ ...properties,
121
+ "@type": type
122
+ };
123
+ if (id !== void 0) node["@id"] = id;
124
+ collector.builder.add(node);
125
+ return null;
126
+ };
127
+ /**
128
+ * Registers one or more Schema.org nodes into the central graph.
129
+ *
130
+ * This component never renders its own script element.
131
+ */
132
+ const SeoJsonLd = ({ data, id, nonce }) => {
133
+ const collector = useSchemaCollector();
134
+ if (nonce) {
135
+ if (collector.nonce && collector.nonce !== nonce) throw new Error("Conflicting CSP nonces were provided to SeoProvider and SeoJsonLd.");
136
+ collector.nonce = nonce;
137
+ }
138
+ if (Array.isArray(data)) {
139
+ collector.builder.addMany(data);
140
+ return null;
141
+ }
142
+ const value = data;
143
+ if (typeof value === "object" && value !== null && "@graph" in value && Array.isArray(value["@graph"])) {
144
+ collector.builder.addMany(value["@graph"]);
145
+ return null;
146
+ }
147
+ if (typeof value !== "object" || value === null || !("@type" in value)) throw new Error("SeoJsonLd requires a Schema.org node or graph.");
148
+ const node = {
149
+ ...value,
150
+ ...id !== void 0 ? { "@id": id } : {}
151
+ };
152
+ collector.builder.add(node);
153
+ return null;
154
+ };
155
+ /**
156
+ * Explicitly named alias for the central JSON-LD registration component.
157
+ *
158
+ * The script itself is still rendered once by SeoProvider.
159
+ */
160
+ const SchemaScript = SeoJsonLd;
161
+ /**
162
+ * Registers an existing collection of nodes or a complete graph.
163
+ *
164
+ * This makes it possible to compose graph data from separate modules
165
+ * without creating additional graph builders or JSON-LD scripts.
166
+ */
167
+ const SchemaGraph = (props) => {
168
+ const collector = useSchemaCollector();
169
+ if (props.graph !== void 0) {
170
+ collector.builder.addMany(props.graph["@graph"]);
171
+ return null;
172
+ }
173
+ collector.builder.addMany(props.nodes);
174
+ return null;
175
+ };
176
+ /**
177
+ * Registers an entity reference in the central graph.
178
+ *
179
+ * A reference without a matching node becomes a minimal Thing node.
180
+ * When a full node with the same @id is registered elsewhere, the graph
181
+ * engine merges the two nodes.
182
+ */
183
+ const SchemaReference = ({ id, type = "Thing" }) => {
184
+ useSchemaCollector().builder.add({
185
+ "@id": id,
186
+ "@type": type
187
+ });
188
+ return null;
189
+ };
190
+ /**
191
+ * Factory for strongly named Schema.org components.
192
+ *
193
+ * The component type is fixed. Properties are derived from the generated
194
+ * Schema.org registry definitions, including inherited properties.
195
+ */
196
+ const createSchemaComponent = (type) => {
197
+ const Component = (props) => {
198
+ const collector = useSchemaCollector();
199
+ return registerSchema(collector, type, props);
200
+ };
201
+ return Component;
202
+ };
203
+ const LDOrganization = createSchemaComponent("Organization");
204
+ const LDPerson = createSchemaComponent("Person");
205
+ const LDWebSite = createSchemaComponent("WebSite");
206
+ /**
207
+ * Alternative spelling for convenience.
208
+ */
209
+ const LDWebsite = LDWebSite;
210
+ const LDWebPage = createSchemaComponent("WebPage");
211
+ const LDArticle = createSchemaComponent("Article");
212
+ const LDBlogPosting = createSchemaComponent("BlogPosting");
213
+ const LDBreadcrumbList = createSchemaComponent("BreadcrumbList");
214
+ const LDBreadcrumbs = LDBreadcrumbList;
215
+ const LDProduct = createSchemaComponent("Product");
216
+ const LDOffer = createSchemaComponent("Offer");
217
+ const LDAggregateRating = createSchemaComponent("AggregateRating");
218
+ const LDReview = createSchemaComponent("Review");
219
+ const LDLocalBusiness = createSchemaComponent("LocalBusiness");
220
+ const LDService = createSchemaComponent("Service");
221
+ const LDImageObject = createSchemaComponent("ImageObject");
222
+ const LDVideoObject = createSchemaComponent("VideoObject");
223
+ const LDEvent = createSchemaComponent("Event");
224
+ const LDRecipe = createSchemaComponent("Recipe");
225
+ const LDCourse = createSchemaComponent("Course");
226
+ const LDJobPosting = createSchemaComponent("JobPosting");
227
+ const LDPlace = createSchemaComponent("Place");
228
+ const LDPostalAddress = createSchemaComponent("PostalAddress");
229
+ const LDContactPoint = createSchemaComponent("ContactPoint");
230
+ const LDSearchAction = createSchemaComponent("SearchAction");
231
+ const LDItemList = createSchemaComponent("ItemList");
232
+ const LDSoftwareApplication = createSchemaComponent("SoftwareApplication");
233
+ const LDHowTo = createSchemaComponent("HowTo");
234
+ const LDFaqPage = createSchemaComponent("FAQPage");
235
+ const LDFAQPage = LDFaqPage;
236
+ const LDCollectionPage = createSchemaComponent("CollectionPage");
237
+ const LDProfilePage = createSchemaComponent("ProfilePage");
238
+ /**
239
+ * Exposes the current SEO configuration to descendant components.
240
+ *
241
+ * The returned registration method is scoped to the current provider.
242
+ */
243
+ const useSeo = () => {
244
+ const collector = useSchemaCollector();
245
+ return {
246
+ config: collector.config,
247
+ registerNode: (node) => {
248
+ collector.builder.add(node);
249
+ }
250
+ };
251
+ };
252
+ export { LDAggregateRating, LDArticle, LDBlogPosting, LDBreadcrumbList, LDBreadcrumbs, LDCollectionPage, LDContactPoint, LDCourse, LDEvent, LDFAQPage, LDFaqPage, LDHowTo, LDImageObject, LDItemList, LDJobPosting, LDLocalBusiness, LDOffer, LDOrganization, LDPerson, LDPlace, LDPostalAddress, LDProduct, LDProfilePage, LDRecipe, LDReview, LDSearchAction, LDService, LDSoftwareApplication, LDVideoObject, LDWebPage, LDWebSite, LDWebsite, Schema, SchemaGraph, SchemaReference, SchemaScript, SeoJsonLd, SeoProvider, assertSeoValidationReport, normalizeValidation, useSeo };
253
+
254
+ //# sourceMappingURL=schema-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-components.js","names":[],"sources":["../../src/react/schema-components.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n createElement,\n Fragment,\n useContext,\n useEffect,\n} from \"react\";\n\nimport { createSeoGraphBuilder, stringifySeoGraph } from \"../core\";\n\nimport type {\n SeoGraph,\n SeoNode,\n SeoGraphBuilder,\n SeoGraphBuilderOptions,\n} from \"../core\";\n\nimport { createDefaultSchemaRegistry } from \"../schema\";\n\nimport type { SchemaRegistry, SchemaValidationOptions } from \"../schema\";\n\nimport type { SeoConfig } from \"../context/types\";\n\nimport type {\n SchemaComponentProps,\n SchemaComponentType,\n SchemaGraphProps,\n SchemaProps,\n SchemaReferenceProps,\n SeoJsonLdProps,\n SeoProviderProps,\n} from \"./types\";\nimport type { ResolvedSeoMetadata } from \"../metadata/types\";\nimport type {\n SeoValidationOptions,\n SeoValidationReport,\n} from \"../validation/types\";\nimport { validateSeo } from \"../validation/validate\";\n\ninterface SchemaCollector {\n config: SeoConfig;\n builder: SeoGraphBuilder;\n registry: SchemaRegistry;\n metadata?: ResolvedSeoMetadata;\n validation: SeoValidationOptions | false;\n onValidation?: (report: SeoValidationReport) => void;\n nonce?: string;\n scriptId: string;\n}\nconst defaultRegistry = createDefaultSchemaRegistry();\n\nconst SchemaContext = createContext<SchemaCollector | null>(null);\n\nconst useSchemaCollector = (): SchemaCollector => {\n const collector = useContext(SchemaContext);\n\n if (!collector) {\n throw new Error(\n \"Puzzle SEO schema components must be rendered inside SeoProvider.\",\n );\n }\n\n return collector;\n};\n\n/**\n * Throws when a strict validation report contains errors.\n */\nexport const assertSeoValidationReport = (report: SeoValidationReport): void => {\n if (report.mode !== \"strict\" || report.valid) {\n return;\n }\n\n const errors = report.issues.filter((issue) => issue.severity === \"error\");\n\n const messages = errors.map(\n (issue) => `[${issue.source}:${issue.code}] ${issue.message}`,\n );\n\n // Keep the established message when only schema rules failed.\n const scope =\n errors.length > 0 &&\n errors.every(\n (issue) => issue.source === \"schema\" || issue.source === \"registry\",\n )\n ? \"schema validation\"\n : \"validation\";\n\n throw new Error(`Puzzle SEO ${scope} failed:\\n${messages.join(\"\\n\")}`);\n};\n\ninterface SchemaGraphOutputProps {\n collector: SchemaCollector;\n}\n\nconst SchemaGraphOutput = ({ collector }: SchemaGraphOutputProps) => {\n const graph = collector.builder.build();\n const graphIssues = collector.builder.getIssues();\n\n const graphErrors = graphIssues.filter((issue) => issue.severity === \"error\");\n\n const report =\n collector.validation !== false\n ? validateSeo(\n {\n graph,\n metadata: collector.metadata,\n },\n {\n ...collector.validation,\n registry: collector.validation.registry ?? collector.registry,\n baseUrl: collector.validation.baseUrl ?? collector.config.siteUrl,\n },\n )\n : undefined;\n\n useEffect(() => {\n if (report && collector.onValidation) {\n collector.onValidation(report);\n }\n }, [report, collector.onValidation]);\n\n if (graphErrors.length > 0) {\n throw new Error(\n `Puzzle SEO graph validation failed:\\n${graphErrors\n .map((issue) => issue.message)\n .join(\"\\n\")}`,\n );\n }\n\n if (report) {\n assertSeoValidationReport(report);\n }\n\n // Metadata-only validation is supported. An empty graph simply means\n // that there is no JSON-LD script to render.\n if (graph[\"@graph\"].length === 0) {\n return null;\n }\n\n const json = stringifySeoGraph(graph, {\n pretty: false,\n safe: true,\n scriptSafe: true,\n validate: true,\n });\n\n return createElement(\"script\", {\n id: collector.scriptId,\n type: \"application/ld+json\",\n nonce: collector.nonce,\n dangerouslySetInnerHTML: {\n __html: json,\n },\n });\n};\n\n/**\n * Legacy options are identified by `strict`, the only property that\n * SeoValidationOptions does not share; `mode` always wins when present.\n */\nconst isLegacyValidation = (\n validation: SeoValidationOptions | SchemaValidationOptions,\n): validation is SchemaValidationOptions =>\n \"strict\" in validation && !(\"mode\" in validation);\n\nexport const normalizeValidation = (\n validation: SeoValidationOptions | SchemaValidationOptions | false,\n): SeoValidationOptions | false => {\n if (validation === false) {\n return false;\n }\n\n if (!isLegacyValidation(validation)) {\n return validation;\n }\n\n const { strict, ...options } = validation;\n\n return {\n ...options,\n mode: strict ? \"strict\" : \"warn\",\n };\n};\n\n/**\n * Props for the internal schema provider. The public SeoProvider resolves\n * page metadata before passing it on, so it arrives here already resolved.\n */\nexport interface SchemaProviderProps extends Omit<\n SeoProviderProps,\n \"metadata\"\n> {\n metadata?: ResolvedSeoMetadata;\n}\n\n/**\n * Central SEO provider.\n *\n * Creates an isolated graph builder for every render.\n * All descendant schema components register into this graph.\n *\n * The final JSON-LD script is rendered after the children.\n */\nexport const SeoProvider = ({\n config,\n children,\n scriptId = \"puzzle-seo-jsonld\",\n nonce,\n graphOptions,\n schemaRegistry,\n metadata,\n validation = {},\n onValidation,\n}: SchemaProviderProps) => {\n const options: SeoGraphBuilderOptions = {\n ...graphOptions,\n baseUrl: graphOptions?.baseUrl ?? config.siteUrl,\n };\n\n const normalizedValidation = normalizeValidation(validation);\n\n const collector: SchemaCollector = {\n config,\n builder: createSeoGraphBuilder(options),\n registry:\n normalizedValidation !== false\n ? (normalizedValidation.registry ?? schemaRegistry ?? defaultRegistry)\n : (schemaRegistry ?? defaultRegistry),\n metadata,\n validation: normalizedValidation,\n onValidation,\n nonce,\n scriptId,\n };\n\n return createElement(\n SchemaContext.Provider,\n {\n value: collector,\n },\n createElement(\n Fragment,\n null,\n children,\n createElement(SchemaGraphOutput, {\n collector,\n }),\n ),\n );\n};\n\n/**\n * Registers a Schema.org node.\n *\n * All properties are preserved. The graph engine is responsible\n * for normalization, references, deduplication and ID generation.\n */\nconst registerSchema = <Type extends SchemaComponentType>(\n collector: SchemaCollector,\n type: Type,\n props: SchemaComponentProps<Type>,\n): null => {\n const { id, data, ...properties } = props;\n\n const node: Record<string, unknown> = {\n ...data,\n ...properties,\n \"@type\": type,\n };\n\n if (id !== undefined) {\n node[\"@id\"] = id;\n }\n\n collector.builder.add(node as SeoNode);\n\n return null;\n};\n\n/**\n * Generic Schema.org component.\n *\n * Supports generated Schema.org definitions and custom types.\n */\nexport const Schema = ({ type, id, data, properties }: SchemaProps) => {\n const collector = useSchemaCollector();\n\n const node: Record<string, unknown> = {\n ...data,\n ...properties,\n \"@type\": type,\n };\n\n if (id !== undefined) {\n node[\"@id\"] = id;\n }\n\n collector.builder.add(node as SeoNode);\n\n return null;\n};\n\n/**\n * Registers one or more Schema.org nodes into the central graph.\n *\n * This component never renders its own script element.\n */\nexport const SeoJsonLd = ({ data, id, nonce }: SeoJsonLdProps) => {\n const collector = useSchemaCollector();\n\n if (nonce) {\n if (collector.nonce && collector.nonce !== nonce) {\n throw new Error(\n \"Conflicting CSP nonces were provided to SeoProvider and SeoJsonLd.\",\n );\n }\n\n collector.nonce = nonce;\n }\n\n if (Array.isArray(data)) {\n collector.builder.addMany(data);\n return null;\n }\n\n const value = data as SeoGraph | SeoNode;\n\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"@graph\" in value &&\n Array.isArray(value[\"@graph\"])\n ) {\n collector.builder.addMany(value[\"@graph\"]);\n return null;\n }\n\n if (typeof value !== \"object\" || value === null || !(\"@type\" in value)) {\n throw new Error(\"SeoJsonLd requires a Schema.org node or graph.\");\n }\n\n const node: SeoNode = {\n ...value,\n ...(id !== undefined ? { \"@id\": id } : {}),\n } as SeoNode;\n\n collector.builder.add(node);\n\n return null;\n};\n\n/**\n * Explicitly named alias for the central JSON-LD registration component.\n *\n * The script itself is still rendered once by SeoProvider.\n */\nexport const SchemaScript = SeoJsonLd;\n\n/**\n * Registers an existing collection of nodes or a complete graph.\n *\n * This makes it possible to compose graph data from separate modules\n * without creating additional graph builders or JSON-LD scripts.\n */\nexport const SchemaGraph = (props: SchemaGraphProps) => {\n const collector = useSchemaCollector();\n\n if (props.graph !== undefined) {\n collector.builder.addMany(props.graph[\"@graph\"]);\n return null;\n }\n\n collector.builder.addMany(props.nodes);\n\n return null;\n};\n\n/**\n * Registers an entity reference in the central graph.\n *\n * A reference without a matching node becomes a minimal Thing node.\n * When a full node with the same @id is registered elsewhere, the graph\n * engine merges the two nodes.\n */\nexport const SchemaReference = ({\n id,\n type = \"Thing\",\n}: SchemaReferenceProps) => {\n const collector = useSchemaCollector();\n\n collector.builder.add({\n \"@id\": id,\n \"@type\": type,\n });\n\n return null;\n};\n\n/**\n * Factory for strongly named Schema.org components.\n *\n * The component type is fixed. Properties are derived from the generated\n * Schema.org registry definitions, including inherited properties.\n */\nconst createSchemaComponent = <Type extends SchemaComponentType>(\n type: Type,\n) => {\n const Component = (props: SchemaComponentProps<Type>): null => {\n const collector = useSchemaCollector();\n\n return registerSchema(collector, type, props);\n };\n\n return Component;\n};\n\n// ---------------------------------------------------------------------------\n// Organization / Person\n// ---------------------------------------------------------------------------\n\nexport const LDOrganization = createSchemaComponent(\"Organization\");\n\nexport const LDPerson = createSchemaComponent(\"Person\");\n\n// ---------------------------------------------------------------------------\n// WebSite / WebPage\n// ---------------------------------------------------------------------------\n\nexport const LDWebSite = createSchemaComponent(\"WebSite\");\n\n/**\n * Alternative spelling for convenience.\n */\nexport const LDWebsite = LDWebSite;\n\nexport const LDWebPage = createSchemaComponent(\"WebPage\");\n\n// ---------------------------------------------------------------------------\n// Article / BlogPosting\n// ---------------------------------------------------------------------------\n\nexport const LDArticle = createSchemaComponent(\"Article\");\n\nexport const LDBlogPosting = createSchemaComponent(\"BlogPosting\");\n\n// ---------------------------------------------------------------------------\n// BreadcrumbList\n// ---------------------------------------------------------------------------\n\nexport const LDBreadcrumbList = createSchemaComponent(\"BreadcrumbList\");\n\nexport const LDBreadcrumbs = LDBreadcrumbList;\n\n// ---------------------------------------------------------------------------\n// Product / Offer / AggregateRating / Review\n// ---------------------------------------------------------------------------\n\nexport const LDProduct = createSchemaComponent(\"Product\");\n\nexport const LDOffer = createSchemaComponent(\"Offer\");\n\nexport const LDAggregateRating = createSchemaComponent(\"AggregateRating\");\n\nexport const LDReview = createSchemaComponent(\"Review\");\n\n// ---------------------------------------------------------------------------\n// LocalBusiness / Service\n// ---------------------------------------------------------------------------\n\nexport const LDLocalBusiness = createSchemaComponent(\"LocalBusiness\");\n\nexport const LDService = createSchemaComponent(\"Service\");\n\n// ---------------------------------------------------------------------------\n// ImageObject / VideoObject / Event\n// ---------------------------------------------------------------------------\n\nexport const LDImageObject = createSchemaComponent(\"ImageObject\");\n\nexport const LDVideoObject = createSchemaComponent(\"VideoObject\");\n\nexport const LDEvent = createSchemaComponent(\"Event\");\n\n// ---------------------------------------------------------------------------\n// Additional Schema.org components\n// ---------------------------------------------------------------------------\n\nexport const LDRecipe = createSchemaComponent(\"Recipe\");\n\nexport const LDCourse = createSchemaComponent(\"Course\");\n\nexport const LDJobPosting = createSchemaComponent(\"JobPosting\");\n\nexport const LDPlace = createSchemaComponent(\"Place\");\n\nexport const LDPostalAddress = createSchemaComponent(\"PostalAddress\");\n\nexport const LDContactPoint = createSchemaComponent(\"ContactPoint\");\n\nexport const LDSearchAction = createSchemaComponent(\"SearchAction\");\n\nexport const LDItemList = createSchemaComponent(\"ItemList\");\n\nexport const LDSoftwareApplication = createSchemaComponent(\n \"SoftwareApplication\",\n);\n\nexport const LDHowTo = createSchemaComponent(\"HowTo\");\n\nexport const LDFaqPage = createSchemaComponent(\"FAQPage\");\n\nexport const LDFAQPage = LDFaqPage;\n\nexport const LDCollectionPage = createSchemaComponent(\"CollectionPage\");\n\nexport const LDProfilePage = createSchemaComponent(\"ProfilePage\");\n\n/**\n * Exposes the current SEO configuration to descendant components.\n *\n * The returned registration method is scoped to the current provider.\n */\nexport const useSeo = () => {\n const collector = useSchemaCollector();\n\n return {\n config: collector.config,\n\n registerNode: (node: SeoNode) => {\n collector.builder.add(node);\n },\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { SeoGraph, SeoGraphBuilderOptions, SeoNode, SeoValidationIssue } from "../core/types.cjs";
2
+ import { SeoConfig, SeoResolvedConfig } from "../context/types.cjs";
3
+ import { ResolvedSeoMetadata, SeoPageMetadata } from "../metadata/types.cjs";
4
+ import { SchemaRegistry, SchemaValidationOptions } from "../schema/types.cjs";
5
+ import { SchemaOrgPropertyNames } from "../schema/generated/schemaorg.cjs";
6
+ import "../schema/generated/index.cjs";
7
+ import { SeoValidationOptions, SeoValidationReport } from "../validation/types.cjs";
8
+ import { ReactNode } from "react";
9
+ export type SchemaComponentType = keyof SchemaOrgPropertyNames;
10
+ export type SchemaValue = string | number | boolean | null | Date | SeoNode | {
11
+ "@id": string;
12
+ } | readonly SchemaValue[] | {
13
+ readonly [property: string]: SchemaValue;
14
+ };
15
+ export type SchemaProperties<Type extends SchemaComponentType = "Thing"> = { [Property in SchemaOrgPropertyNames[Type]]?: SchemaValue; };
16
+ export type SchemaComponentProps<Type extends SchemaComponentType = "Thing"> = SchemaProperties<Type> & {
17
+ id?: string;
18
+ data?: Readonly<Record<string, SchemaValue>>;
19
+ };
20
+ export interface SchemaProps {
21
+ type: string;
22
+ id?: string;
23
+ data?: Readonly<Record<string, SchemaValue>>;
24
+ properties?: Readonly<Record<string, SchemaValue>>;
25
+ }
26
+ export interface SchemaReferenceProps {
27
+ id: string;
28
+ type?: SchemaComponentType;
29
+ }
30
+ export type SchemaGraphProps = {
31
+ nodes: readonly SeoNode[];
32
+ graph?: never;
33
+ } | {
34
+ graph: SeoGraph;
35
+ nodes?: never;
36
+ };
37
+ export interface SeoProviderProps {
38
+ config: SeoConfig;
39
+ children: ReactNode;
40
+ metadata?: SeoPageMetadata;
41
+ scriptId?: string;
42
+ nonce?: string;
43
+ graphOptions?: SeoGraphBuilderOptions;
44
+ schemaRegistry?: SchemaRegistry;
45
+ /**
46
+ * Controls validation of the complete SEO output.
47
+ *
48
+ * false disables validation.
49
+ *
50
+ * Legacy SchemaValidationOptions are still supported.
51
+ */
52
+ validation?: SeoValidationOptions | SchemaValidationOptions | false;
53
+ /**
54
+ * Receives validation diagnostics after rendering.
55
+ *
56
+ * In warn mode the JSON-LD output is still rendered.
57
+ * In strict mode invalid output throws before rendering.
58
+ */
59
+ onValidation?: (report: SeoValidationReport) => void;
60
+ }
61
+ export interface SeoContextValue {
62
+ config: SeoResolvedConfig;
63
+ metadata?: ResolvedSeoMetadata;
64
+ registerNode: (node: SeoNode) => void;
65
+ }
66
+ export interface SeoMetadataProps {
67
+ metadata: SeoPageMetadata;
68
+ children?: ReactNode;
69
+ }
70
+ export interface SeoJsonLdProps {
71
+ data: SeoNode | SeoGraph | readonly SeoNode[];
72
+ id?: string;
73
+ nonce?: string;
74
+ }
75
+ export interface SeoHeadProps {
76
+ children?: ReactNode;
77
+ }
78
+ export interface SeoSchemaValidationError {
79
+ nodeId?: string;
80
+ issues: readonly SeoValidationIssue[];
81
+ }
@@ -0,0 +1,80 @@
1
+ import { SeoGraph, SeoGraphBuilderOptions, SeoNode, SeoValidationIssue } from "../core/types.js";
2
+ import { SeoConfig, SeoResolvedConfig } from "../context/types.js";
3
+ import { ResolvedSeoMetadata, SeoPageMetadata } from "../metadata/types.js";
4
+ import { SchemaRegistry, SchemaValidationOptions } from "../schema/types.js";
5
+ import { SchemaOrgPropertyNames } from "../schema/generated/schemaorg.js";
6
+ import { SeoValidationOptions, SeoValidationReport } from "../validation/types.js";
7
+ import { ReactNode } from "react";
8
+ export type SchemaComponentType = keyof SchemaOrgPropertyNames;
9
+ export type SchemaValue = string | number | boolean | null | Date | SeoNode | {
10
+ "@id": string;
11
+ } | readonly SchemaValue[] | {
12
+ readonly [property: string]: SchemaValue;
13
+ };
14
+ export type SchemaProperties<Type extends SchemaComponentType = "Thing"> = { [Property in SchemaOrgPropertyNames[Type]]?: SchemaValue; };
15
+ export type SchemaComponentProps<Type extends SchemaComponentType = "Thing"> = SchemaProperties<Type> & {
16
+ id?: string;
17
+ data?: Readonly<Record<string, SchemaValue>>;
18
+ };
19
+ export interface SchemaProps {
20
+ type: string;
21
+ id?: string;
22
+ data?: Readonly<Record<string, SchemaValue>>;
23
+ properties?: Readonly<Record<string, SchemaValue>>;
24
+ }
25
+ export interface SchemaReferenceProps {
26
+ id: string;
27
+ type?: SchemaComponentType;
28
+ }
29
+ export type SchemaGraphProps = {
30
+ nodes: readonly SeoNode[];
31
+ graph?: never;
32
+ } | {
33
+ graph: SeoGraph;
34
+ nodes?: never;
35
+ };
36
+ export interface SeoProviderProps {
37
+ config: SeoConfig;
38
+ children: ReactNode;
39
+ metadata?: SeoPageMetadata;
40
+ scriptId?: string;
41
+ nonce?: string;
42
+ graphOptions?: SeoGraphBuilderOptions;
43
+ schemaRegistry?: SchemaRegistry;
44
+ /**
45
+ * Controls validation of the complete SEO output.
46
+ *
47
+ * false disables validation.
48
+ *
49
+ * Legacy SchemaValidationOptions are still supported.
50
+ */
51
+ validation?: SeoValidationOptions | SchemaValidationOptions | false;
52
+ /**
53
+ * Receives validation diagnostics after rendering.
54
+ *
55
+ * In warn mode the JSON-LD output is still rendered.
56
+ * In strict mode invalid output throws before rendering.
57
+ */
58
+ onValidation?: (report: SeoValidationReport) => void;
59
+ }
60
+ export interface SeoContextValue {
61
+ config: SeoResolvedConfig;
62
+ metadata?: ResolvedSeoMetadata;
63
+ registerNode: (node: SeoNode) => void;
64
+ }
65
+ export interface SeoMetadataProps {
66
+ metadata: SeoPageMetadata;
67
+ children?: ReactNode;
68
+ }
69
+ export interface SeoJsonLdProps {
70
+ data: SeoNode | SeoGraph | readonly SeoNode[];
71
+ id?: string;
72
+ nonce?: string;
73
+ }
74
+ export interface SeoHeadProps {
75
+ children?: ReactNode;
76
+ }
77
+ export interface SeoSchemaValidationError {
78
+ nodeId?: string;
79
+ issues: readonly SeoValidationIssue[];
80
+ }
@@ -0,0 +1,13 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_routes = require("../server/routes.cjs");
3
+ // src/react-router/index.ts
4
+ const createReactRouterSeoRoutes = (options) => {
5
+ const handlers = require_routes.createSeoRouteHandlers(options);
6
+ return {
7
+ sitemapLoader: ({ request }) => handlers.sitemap(request),
8
+ robotsLoader: ({ request }) => handlers.robots(request)
9
+ };
10
+ };
11
+ exports.createReactRouterSeoRoutes = createReactRouterSeoRoutes;
12
+
13
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["createSeoRouteHandlers"],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createSeoRouteHandlers } from \"../server\";\n\nimport type { SeoRouteOptions } from \"../server\";\n\nexport interface ReactRouterLoaderArgs {\n request: Request;\n params: Record<string, string | undefined>;\n context: unknown;\n}\n\nexport type ReactRouterSeoLoader = (\n args: ReactRouterLoaderArgs,\n) => Promise<Response>;\n\nexport interface ReactRouterSeoRoutes {\n /**\n * Mount on a dynamic root resource route, e.g. /:seoFile.\n *\n * Handles the sitemap index and every generated sitemap file.\n */\n sitemapLoader: ReactRouterSeoLoader;\n\n /**\n * Mount on the static /robots.txt resource route.\n */\n robotsLoader: ReactRouterSeoLoader;\n}\n\nexport const createReactRouterSeoRoutes = (\n options: SeoRouteOptions,\n): ReactRouterSeoRoutes => {\n const handlers = createSeoRouteHandlers(options);\n\n return {\n sitemapLoader: ({ request }) => handlers.sitemap(request),\n robotsLoader: ({ request }) => handlers.robots(request),\n };\n};\n"],"mappings":";;;AA4BA,MAAa,8BACX,YACyB;CACzB,MAAM,WAAWA,eAAAA,uBAAuB,OAAO;CAE/C,OAAO;EACL,gBAAgB,EAAE,cAAc,SAAS,QAAQ,OAAO;EACxD,eAAe,EAAE,cAAc,SAAS,OAAO,OAAO;CACxD;AACF"}
@@ -0,0 +1,21 @@
1
+ import { SeoRouteOptions } from "../server/types.cjs";
2
+ import "../server/index.cjs";
3
+ export interface ReactRouterLoaderArgs {
4
+ request: Request;
5
+ params: Record<string, string | undefined>;
6
+ context: unknown;
7
+ }
8
+ export type ReactRouterSeoLoader = (args: ReactRouterLoaderArgs) => Promise<Response>;
9
+ export interface ReactRouterSeoRoutes {
10
+ /**
11
+ * Mount on a dynamic root resource route, e.g. /:seoFile.
12
+ *
13
+ * Handles the sitemap index and every generated sitemap file.
14
+ */
15
+ sitemapLoader: ReactRouterSeoLoader;
16
+ /**
17
+ * Mount on the static /robots.txt resource route.
18
+ */
19
+ robotsLoader: ReactRouterSeoLoader;
20
+ }
21
+ export declare const createReactRouterSeoRoutes: (options: SeoRouteOptions) => ReactRouterSeoRoutes;
@@ -0,0 +1,20 @@
1
+ import { SeoRouteOptions } from "../server/types.js";
2
+ export interface ReactRouterLoaderArgs {
3
+ request: Request;
4
+ params: Record<string, string | undefined>;
5
+ context: unknown;
6
+ }
7
+ export type ReactRouterSeoLoader = (args: ReactRouterLoaderArgs) => Promise<Response>;
8
+ export interface ReactRouterSeoRoutes {
9
+ /**
10
+ * Mount on a dynamic root resource route, e.g. /:seoFile.
11
+ *
12
+ * Handles the sitemap index and every generated sitemap file.
13
+ */
14
+ sitemapLoader: ReactRouterSeoLoader;
15
+ /**
16
+ * Mount on the static /robots.txt resource route.
17
+ */
18
+ robotsLoader: ReactRouterSeoLoader;
19
+ }
20
+ export declare const createReactRouterSeoRoutes: (options: SeoRouteOptions) => ReactRouterSeoRoutes;
@@ -0,0 +1,12 @@
1
+ import { createSeoRouteHandlers } from "../server/routes.js";
2
+ // src/react-router/index.ts
3
+ const createReactRouterSeoRoutes = (options) => {
4
+ const handlers = createSeoRouteHandlers(options);
5
+ return {
6
+ sitemapLoader: ({ request }) => handlers.sitemap(request),
7
+ robotsLoader: ({ request }) => handlers.robots(request)
8
+ };
9
+ };
10
+ export { createReactRouterSeoRoutes };
11
+
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createSeoRouteHandlers } from \"../server\";\n\nimport type { SeoRouteOptions } from \"../server\";\n\nexport interface ReactRouterLoaderArgs {\n request: Request;\n params: Record<string, string | undefined>;\n context: unknown;\n}\n\nexport type ReactRouterSeoLoader = (\n args: ReactRouterLoaderArgs,\n) => Promise<Response>;\n\nexport interface ReactRouterSeoRoutes {\n /**\n * Mount on a dynamic root resource route, e.g. /:seoFile.\n *\n * Handles the sitemap index and every generated sitemap file.\n */\n sitemapLoader: ReactRouterSeoLoader;\n\n /**\n * Mount on the static /robots.txt resource route.\n */\n robotsLoader: ReactRouterSeoLoader;\n}\n\nexport const createReactRouterSeoRoutes = (\n options: SeoRouteOptions,\n): ReactRouterSeoRoutes => {\n const handlers = createSeoRouteHandlers(options);\n\n return {\n sitemapLoader: ({ request }) => handlers.sitemap(request),\n robotsLoader: ({ request }) => handlers.robots(request),\n };\n};\n"],"mappings":";;AA4BA,MAAa,8BACX,YACyB;CACzB,MAAM,WAAW,uBAAuB,OAAO;CAE/C,OAAO;EACL,gBAAgB,EAAE,cAAc,SAAS,QAAQ,OAAO;EACxD,eAAe,EAAE,cAAc,SAAS,OAAO,OAAO;CACxD;AACF"}
@@ -0,0 +1,88 @@
1
+ const require_normalize = require("../urls/normalize.cjs");
2
+ // src/robots/generate.ts
3
+ const validateRule = (rule, index) => {
4
+ const issues = [];
5
+ const agents = Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent];
6
+ if (agents.length === 0 || agents.some((agent) => !agent.trim() || /[\r\n]/.test(agent))) issues.push({
7
+ code: "INVALID_USER_AGENT",
8
+ message: "Every robots rule requires a non-empty user-agent without newlines.",
9
+ path: `rules.${index}.userAgent`
10
+ });
11
+ if (rule.crawlDelay !== void 0 && (!Number.isFinite(rule.crawlDelay) || rule.crawlDelay < 0)) issues.push({
12
+ code: "INVALID_CRAWL_DELAY",
13
+ message: "Crawl-delay must be a non-negative number.",
14
+ path: `rules.${index}.crawlDelay`
15
+ });
16
+ for (const [name, paths] of [["allow", rule.allow], ["disallow", rule.disallow]]) {
17
+ if (!paths) continue;
18
+ for (const path of paths) if (!path.startsWith("/") || /[\r\n]/.test(path)) issues.push({
19
+ code: "INVALID_ROBOTS_PATH",
20
+ message: `${name} paths must start with / and contain no newlines.`,
21
+ path: `rules.${index}.${name}`
22
+ });
23
+ }
24
+ return issues;
25
+ };
26
+ const validateRobotsOptions = (options) => {
27
+ const issues = [];
28
+ if (!options.rules.length) issues.push({
29
+ code: "MISSING_RULES",
30
+ message: "At least one robots rule is required."
31
+ });
32
+ options.rules.forEach((rule, index) => {
33
+ issues.push(...validateRule(rule, index));
34
+ });
35
+ for (const sitemap of Array.isArray(options.sitemap) ? options.sitemap : options.sitemap ? [options.sitemap] : []) try {
36
+ require_normalize.normalizeSeoUrl(sitemap);
37
+ } catch {
38
+ issues.push({
39
+ code: "INVALID_SITEMAP_URL",
40
+ message: `Invalid sitemap URL: ${sitemap}.`
41
+ });
42
+ }
43
+ if (options.host && /[\r\n]/.test(options.host)) issues.push({
44
+ code: "INVALID_HOST",
45
+ message: "Robots host must not contain newlines."
46
+ });
47
+ return issues;
48
+ };
49
+ const serializeRule = (rule) => {
50
+ const lines = (Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent]).map((agent) => `User-agent: ${agent.trim()}`);
51
+ for (const path of rule.allow ?? []) lines.push(`Allow: ${path}`);
52
+ for (const path of rule.disallow ?? []) lines.push(`Disallow: ${path}`);
53
+ if (rule.crawlDelay !== void 0) lines.push(`Crawl-delay: ${rule.crawlDelay}`);
54
+ return lines;
55
+ };
56
+ const serializeRobotsTxt = (options) => {
57
+ const issues = validateRobotsOptions(options);
58
+ if (issues.length > 0) throw new Error(`Invalid robots configuration: ${issues.map((issue) => issue.message).join(" ")}`);
59
+ const groups = options.rules.map(serializeRule);
60
+ const lines = [];
61
+ groups.forEach((group, index) => {
62
+ if (index > 0) lines.push("");
63
+ lines.push(...group);
64
+ });
65
+ const sitemaps = [...new Set((Array.isArray(options.sitemap) ? options.sitemap : options.sitemap ? [options.sitemap] : []).map((url) => require_normalize.normalizeSeoUrl(url)))].sort();
66
+ if (sitemaps.length > 0) {
67
+ lines.push("");
68
+ for (const sitemap of sitemaps) lines.push(`Sitemap: ${sitemap}`);
69
+ }
70
+ if (options.host) lines.push(`Host: ${options.host}`);
71
+ return `${lines.join("\n")}\n`;
72
+ };
73
+ const generateRobotsTxt = (options) => {
74
+ const issues = validateRobotsOptions(options);
75
+ if (issues.length > 0) return {
76
+ content: "",
77
+ issues
78
+ };
79
+ return {
80
+ content: serializeRobotsTxt(options),
81
+ issues: []
82
+ };
83
+ };
84
+ exports.generateRobotsTxt = generateRobotsTxt;
85
+ exports.serializeRobotsTxt = serializeRobotsTxt;
86
+ exports.validateRobotsOptions = validateRobotsOptions;
87
+
88
+ //# sourceMappingURL=generate.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.cjs","names":["normalizeSeoUrl"],"sources":["../../src/robots/generate.ts"],"sourcesContent":["import { normalizeSeoUrl } from \"../urls\";\n\nimport type {\n RobotsOptions,\n RobotsRule,\n RobotsResult,\n RobotsValidationIssue,\n} from \"./types\";\n\nconst validateRule = (\n rule: RobotsRule,\n index: number,\n): RobotsValidationIssue[] => {\n const issues: RobotsValidationIssue[] = [];\n\n const agents = Array.isArray(rule.userAgent)\n ? rule.userAgent\n : [rule.userAgent];\n\n if (\n agents.length === 0 ||\n agents.some((agent) => !agent.trim() || /[\\r\\n]/.test(agent))\n ) {\n issues.push({\n code: \"INVALID_USER_AGENT\",\n message:\n \"Every robots rule requires a non-empty user-agent without newlines.\",\n path: `rules.${index}.userAgent`,\n });\n }\n\n if (\n rule.crawlDelay !== undefined &&\n (!Number.isFinite(rule.crawlDelay) || rule.crawlDelay < 0)\n ) {\n issues.push({\n code: \"INVALID_CRAWL_DELAY\",\n message: \"Crawl-delay must be a non-negative number.\",\n path: `rules.${index}.crawlDelay`,\n });\n }\n\n for (const [name, paths] of [\n [\"allow\", rule.allow],\n [\"disallow\", rule.disallow],\n ] as const) {\n if (!paths) {\n continue;\n }\n\n for (const path of paths) {\n if (!path.startsWith(\"/\") || /[\\r\\n]/.test(path)) {\n issues.push({\n code: \"INVALID_ROBOTS_PATH\",\n message: `${name} paths must start with / and contain no newlines.`,\n path: `rules.${index}.${name}`,\n });\n }\n }\n }\n\n return issues;\n};\n\nexport const validateRobotsOptions = (\n options: RobotsOptions,\n): RobotsValidationIssue[] => {\n const issues: RobotsValidationIssue[] = [];\n\n if (!options.rules.length) {\n issues.push({\n code: \"MISSING_RULES\",\n message: \"At least one robots rule is required.\",\n });\n }\n\n options.rules.forEach((rule, index) => {\n issues.push(...validateRule(rule, index));\n });\n\n for (const sitemap of Array.isArray(options.sitemap)\n ? options.sitemap\n : options.sitemap\n ? [options.sitemap]\n : []) {\n try {\n normalizeSeoUrl(sitemap);\n } catch {\n issues.push({\n code: \"INVALID_SITEMAP_URL\",\n message: `Invalid sitemap URL: ${sitemap}.`,\n });\n }\n }\n\n if (options.host && /[\\r\\n]/.test(options.host)) {\n issues.push({\n code: \"INVALID_HOST\",\n message: \"Robots host must not contain newlines.\",\n });\n }\n\n return issues;\n};\n\nconst serializeRule = (rule: RobotsRule): string[] => {\n const agents = Array.isArray(rule.userAgent)\n ? rule.userAgent\n : [rule.userAgent];\n\n const lines = agents.map((agent) => `User-agent: ${agent.trim()}`);\n\n for (const path of rule.allow ?? []) {\n lines.push(`Allow: ${path}`);\n }\n\n for (const path of rule.disallow ?? []) {\n lines.push(`Disallow: ${path}`);\n }\n\n if (rule.crawlDelay !== undefined) {\n lines.push(`Crawl-delay: ${rule.crawlDelay}`);\n }\n\n return lines;\n};\n\nexport const serializeRobotsTxt = (options: RobotsOptions): string => {\n const issues = validateRobotsOptions(options);\n\n if (issues.length > 0) {\n throw new Error(\n `Invalid robots configuration: ${issues\n .map((issue) => issue.message)\n .join(\" \")}`,\n );\n }\n\n const groups = options.rules.map(serializeRule);\n\n const lines: string[] = [];\n\n groups.forEach((group, index) => {\n if (index > 0) {\n lines.push(\"\");\n }\n\n lines.push(...group);\n });\n\n const sitemaps = [\n ...new Set(\n (Array.isArray(options.sitemap)\n ? options.sitemap\n : options.sitemap\n ? [options.sitemap]\n : []\n ).map((url) => normalizeSeoUrl(url)),\n ),\n ].sort();\n\n if (sitemaps.length > 0) {\n lines.push(\"\");\n\n for (const sitemap of sitemaps) {\n lines.push(`Sitemap: ${sitemap}`);\n }\n }\n\n if (options.host) {\n lines.push(`Host: ${options.host}`);\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n};\n\nexport const generateRobotsTxt = (options: RobotsOptions): RobotsResult => {\n const issues = validateRobotsOptions(options);\n\n if (issues.length > 0) {\n return {\n content: \"\",\n issues,\n };\n }\n\n return {\n content: serializeRobotsTxt(options),\n issues: [],\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { RobotsOptions, RobotsResult, RobotsValidationIssue } from "./types.cjs";
2
+ export declare const validateRobotsOptions: (options: RobotsOptions) => RobotsValidationIssue[];
3
+ export declare const serializeRobotsTxt: (options: RobotsOptions) => string;
4
+ export declare const generateRobotsTxt: (options: RobotsOptions) => RobotsResult;
@@ -0,0 +1,4 @@
1
+ import { RobotsOptions, RobotsResult, RobotsValidationIssue } from "./types.js";
2
+ export declare const validateRobotsOptions: (options: RobotsOptions) => RobotsValidationIssue[];
3
+ export declare const serializeRobotsTxt: (options: RobotsOptions) => string;
4
+ export declare const generateRobotsTxt: (options: RobotsOptions) => RobotsResult;