@actuate-media/plugin-seo 0.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 (65) hide show
  1. package/dist/admin/GooglePreview.d.ts +9 -0
  2. package/dist/admin/GooglePreview.d.ts.map +1 -0
  3. package/dist/admin/GooglePreview.js +67 -0
  4. package/dist/admin/GooglePreview.js.map +1 -0
  5. package/dist/admin/SEOPanel.d.ts +11 -0
  6. package/dist/admin/SEOPanel.d.ts.map +1 -0
  7. package/dist/admin/SEOPanel.js +65 -0
  8. package/dist/admin/SEOPanel.js.map +1 -0
  9. package/dist/admin/SchemaPreview.d.ts +7 -0
  10. package/dist/admin/SchemaPreview.d.ts.map +1 -0
  11. package/dist/admin/SchemaPreview.js +83 -0
  12. package/dist/admin/SchemaPreview.js.map +1 -0
  13. package/dist/canonical/index.d.ts +16 -0
  14. package/dist/canonical/index.d.ts.map +1 -0
  15. package/dist/canonical/index.js +77 -0
  16. package/dist/canonical/index.js.map +1 -0
  17. package/dist/collections.d.ts +3 -0
  18. package/dist/collections.d.ts.map +1 -0
  19. package/dist/collections.js +2 -0
  20. package/dist/collections.js.map +1 -0
  21. package/dist/fields.d.ts +3 -0
  22. package/dist/fields.d.ts.map +1 -0
  23. package/dist/fields.js +115 -0
  24. package/dist/fields.js.map +1 -0
  25. package/dist/hooks.d.ts +5 -0
  26. package/dist/hooks.d.ts.map +1 -0
  27. package/dist/hooks.js +29 -0
  28. package/dist/hooks.js.map +1 -0
  29. package/dist/index.d.ts +72 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +35 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/link-health/index.d.ts +24 -0
  34. package/dist/link-health/index.d.ts.map +1 -0
  35. package/dist/link-health/index.js +82 -0
  36. package/dist/link-health/index.js.map +1 -0
  37. package/dist/og-image/index.d.ts +11 -0
  38. package/dist/og-image/index.d.ts.map +1 -0
  39. package/dist/og-image/index.js +28 -0
  40. package/dist/og-image/index.js.map +1 -0
  41. package/dist/robots/index.d.ts +14 -0
  42. package/dist/robots/index.d.ts.map +1 -0
  43. package/dist/robots/index.js +48 -0
  44. package/dist/robots/index.js.map +1 -0
  45. package/dist/schema/auto-detect.d.ts +3 -0
  46. package/dist/schema/auto-detect.d.ts.map +1 -0
  47. package/dist/schema/auto-detect.js +28 -0
  48. package/dist/schema/auto-detect.js.map +1 -0
  49. package/dist/schema/composer.d.ts +3 -0
  50. package/dist/schema/composer.d.ts.map +1 -0
  51. package/dist/schema/composer.js +72 -0
  52. package/dist/schema/composer.js.map +1 -0
  53. package/dist/schema/registry.d.ts +170 -0
  54. package/dist/schema/registry.d.ts.map +1 -0
  55. package/dist/schema/registry.js +2 -0
  56. package/dist/schema/registry.js.map +1 -0
  57. package/dist/schema/validator.d.ts +11 -0
  58. package/dist/schema/validator.d.ts.map +1 -0
  59. package/dist/schema/validator.js +107 -0
  60. package/dist/schema/validator.js.map +1 -0
  61. package/dist/sitemap/index.d.ts +78 -0
  62. package/dist/sitemap/index.d.ts.map +1 -0
  63. package/dist/sitemap/index.js +186 -0
  64. package/dist/sitemap/index.js.map +1 -0
  65. package/package.json +37 -0
@@ -0,0 +1,170 @@
1
+ export interface SchemaOrgThing {
2
+ "@context"?: string;
3
+ "@type": string;
4
+ name?: string;
5
+ description?: string;
6
+ url?: string;
7
+ image?: string | string[];
8
+ sameAs?: string[];
9
+ }
10
+ export interface SchemaOrgArticle extends SchemaOrgThing {
11
+ "@type": "Article";
12
+ headline: string;
13
+ author: SchemaOrgPerson | SchemaOrgOrganization;
14
+ publisher?: SchemaOrgOrganization;
15
+ datePublished: string;
16
+ dateModified?: string;
17
+ articleBody?: string;
18
+ wordCount?: number;
19
+ keywords?: string[];
20
+ articleSection?: string;
21
+ thumbnailUrl?: string;
22
+ }
23
+ export interface SchemaOrgPerson extends SchemaOrgThing {
24
+ "@type": "Person";
25
+ givenName?: string;
26
+ familyName?: string;
27
+ email?: string;
28
+ telephone?: string;
29
+ jobTitle?: string;
30
+ affiliation?: SchemaOrgOrganization;
31
+ address?: SchemaOrgPostalAddress;
32
+ }
33
+ export interface SchemaOrgOrganization extends SchemaOrgThing {
34
+ "@type": "Organization";
35
+ logo?: string;
36
+ email?: string;
37
+ telephone?: string;
38
+ address?: SchemaOrgPostalAddress;
39
+ foundingDate?: string;
40
+ numberOfEmployees?: number;
41
+ }
42
+ export interface SchemaOrgWebPage extends SchemaOrgThing {
43
+ "@type": "WebPage";
44
+ breadcrumb?: string;
45
+ mainEntity?: SchemaOrgThing;
46
+ lastReviewed?: string;
47
+ primaryImageOfPage?: string;
48
+ significantLink?: string[];
49
+ }
50
+ export interface SchemaOrgEvent extends SchemaOrgThing {
51
+ "@type": "Event";
52
+ startDate: string;
53
+ endDate?: string;
54
+ location?: SchemaOrgPlace | string;
55
+ organizer?: SchemaOrgOrganization | SchemaOrgPerson;
56
+ performer?: SchemaOrgPerson | SchemaOrgOrganization;
57
+ eventStatus?: "EventScheduled" | "EventCancelled" | "EventPostponed" | "EventRescheduled";
58
+ eventAttendanceMode?: "OfflineEventAttendanceMode" | "OnlineEventAttendanceMode" | "MixedEventAttendanceMode";
59
+ offers?: SchemaOrgOffer[];
60
+ }
61
+ export interface SchemaOrgFAQPage extends SchemaOrgThing {
62
+ "@type": "FAQPage";
63
+ mainEntity: Array<{
64
+ "@type": "Question";
65
+ name: string;
66
+ acceptedAnswer: {
67
+ "@type": "Answer";
68
+ text: string;
69
+ };
70
+ }>;
71
+ }
72
+ export interface SchemaOrgService extends SchemaOrgThing {
73
+ "@type": "Service";
74
+ provider?: SchemaOrgOrganization | SchemaOrgPerson;
75
+ serviceType?: string;
76
+ areaServed?: string;
77
+ hasOfferCatalog?: {
78
+ "@type": "OfferCatalog";
79
+ name: string;
80
+ itemListElement: SchemaOrgOffer[];
81
+ };
82
+ }
83
+ export interface SchemaOrgJobPosting extends SchemaOrgThing {
84
+ "@type": "JobPosting";
85
+ title: string;
86
+ datePosted: string;
87
+ validThrough?: string;
88
+ hiringOrganization: SchemaOrgOrganization;
89
+ jobLocation?: SchemaOrgPlace;
90
+ employmentType?: string | string[];
91
+ baseSalary?: {
92
+ "@type": "MonetaryAmount";
93
+ currency: string;
94
+ value: number | {
95
+ "@type": "QuantitativeValue";
96
+ minValue: number;
97
+ maxValue: number;
98
+ };
99
+ };
100
+ jobLocationType?: string;
101
+ }
102
+ export type SchemaOrgLocalBusiness = Omit<SchemaOrgOrganization, "@type"> & {
103
+ "@type": "LocalBusiness";
104
+ priceRange?: string;
105
+ openingHours?: string[];
106
+ geo?: {
107
+ "@type": "GeoCoordinates";
108
+ latitude: number;
109
+ longitude: number;
110
+ };
111
+ hasMap?: string;
112
+ servesCuisine?: string;
113
+ };
114
+ export interface SchemaOrgReview extends SchemaOrgThing {
115
+ "@type": "Review";
116
+ itemReviewed: SchemaOrgThing;
117
+ author: SchemaOrgPerson | SchemaOrgOrganization;
118
+ reviewRating: {
119
+ "@type": "Rating";
120
+ ratingValue: number;
121
+ bestRating?: number;
122
+ worstRating?: number;
123
+ };
124
+ reviewBody?: string;
125
+ datePublished?: string;
126
+ }
127
+ export interface SchemaOrgProduct extends SchemaOrgThing {
128
+ "@type": "Product";
129
+ brand?: SchemaOrgOrganization | {
130
+ "@type": "Brand";
131
+ name: string;
132
+ };
133
+ sku?: string;
134
+ gtin?: string;
135
+ mpn?: string;
136
+ offers?: SchemaOrgOffer | SchemaOrgOffer[];
137
+ aggregateRating?: {
138
+ "@type": "AggregateRating";
139
+ ratingValue: number;
140
+ reviewCount: number;
141
+ bestRating?: number;
142
+ };
143
+ review?: SchemaOrgReview[];
144
+ color?: string;
145
+ material?: string;
146
+ weight?: string;
147
+ }
148
+ interface SchemaOrgPostalAddress {
149
+ "@type": "PostalAddress";
150
+ streetAddress?: string;
151
+ addressLocality?: string;
152
+ addressRegion?: string;
153
+ postalCode?: string;
154
+ addressCountry?: string;
155
+ }
156
+ interface SchemaOrgPlace {
157
+ "@type": "Place";
158
+ name?: string;
159
+ address?: SchemaOrgPostalAddress;
160
+ }
161
+ interface SchemaOrgOffer {
162
+ "@type": "Offer";
163
+ price?: number | string;
164
+ priceCurrency?: string;
165
+ availability?: string;
166
+ url?: string;
167
+ validFrom?: string;
168
+ }
169
+ export {};
170
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ export interface ValidationResult {
2
+ valid: boolean;
3
+ errors: Array<{
4
+ field: string;
5
+ message: string;
6
+ severity: "error" | "warning";
7
+ }>;
8
+ }
9
+ /** Validates a JSON-LD schema object against Schema.org requirements. */
10
+ export declare function validateSchema(schema: Record<string, unknown>): ValidationResult;
11
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;KAC/B,CAAC,CAAC;CACJ;AA8BD,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAqFhF"}
@@ -0,0 +1,107 @@
1
+ const REQUIRED_FIELDS = {
2
+ Article: ["headline", "author", "datePublished"],
3
+ WebPage: ["name"],
4
+ Person: ["name"],
5
+ Organization: ["name"],
6
+ Event: ["name", "startDate"],
7
+ FAQPage: ["mainEntity"],
8
+ Service: ["name"],
9
+ JobPosting: ["title", "datePosted", "hiringOrganization"],
10
+ LocalBusiness: ["name", "address"],
11
+ Review: ["itemReviewed", "author", "reviewRating"],
12
+ Product: ["name"],
13
+ };
14
+ const RECOMMENDED_FIELDS = {
15
+ Article: ["image", "publisher", "dateModified", "description"],
16
+ WebPage: ["description", "url"],
17
+ Person: ["image", "url"],
18
+ Organization: ["logo", "url"],
19
+ Event: ["endDate", "location", "description", "image"],
20
+ FAQPage: [],
21
+ Service: ["provider", "description"],
22
+ JobPosting: ["description", "employmentType", "baseSalary", "validThrough"],
23
+ LocalBusiness: ["telephone", "openingHours", "geo"],
24
+ Review: ["reviewBody", "datePublished"],
25
+ Product: ["image", "description", "offers", "brand"],
26
+ };
27
+ /** Validates a JSON-LD schema object against Schema.org requirements. */
28
+ export function validateSchema(schema) {
29
+ const errors = [];
30
+ const type = schema["@type"];
31
+ if (!schema["@context"]) {
32
+ errors.push({
33
+ field: "@context",
34
+ message: "Missing @context — should be \"https://schema.org\"",
35
+ severity: "error",
36
+ });
37
+ }
38
+ if (!type) {
39
+ errors.push({
40
+ field: "@type",
41
+ message: "Missing @type — every schema object must declare a type",
42
+ severity: "error",
43
+ });
44
+ return { valid: false, errors };
45
+ }
46
+ const required = REQUIRED_FIELDS[type] ?? [];
47
+ for (const field of required) {
48
+ if (schema[field] === undefined || schema[field] === null || schema[field] === "") {
49
+ errors.push({
50
+ field,
51
+ message: `Required field "${field}" is missing for type ${type}`,
52
+ severity: "error",
53
+ });
54
+ }
55
+ }
56
+ const recommended = RECOMMENDED_FIELDS[type] ?? [];
57
+ for (const field of recommended) {
58
+ if (schema[field] === undefined || schema[field] === null || schema[field] === "") {
59
+ errors.push({
60
+ field,
61
+ message: `Recommended field "${field}" is missing for type ${type}`,
62
+ severity: "warning",
63
+ });
64
+ }
65
+ }
66
+ if (type === "Article") {
67
+ const headline = schema["headline"];
68
+ if (typeof headline === "string" && headline.length > 110) {
69
+ errors.push({
70
+ field: "headline",
71
+ message: "Headline exceeds 110 characters — may be truncated in search results",
72
+ severity: "warning",
73
+ });
74
+ }
75
+ }
76
+ if (type === "FAQPage" && Array.isArray(schema["mainEntity"])) {
77
+ const questions = schema["mainEntity"];
78
+ for (let i = 0; i < questions.length; i++) {
79
+ const q = questions[i];
80
+ if (q["@type"] !== "Question") {
81
+ errors.push({
82
+ field: `mainEntity[${i}].@type`,
83
+ message: "FAQ items must have @type \"Question\"",
84
+ severity: "error",
85
+ });
86
+ }
87
+ if (!q["name"]) {
88
+ errors.push({
89
+ field: `mainEntity[${i}].name`,
90
+ message: "FAQ question is missing the \"name\" field (the question text)",
91
+ severity: "error",
92
+ });
93
+ }
94
+ const answer = q["acceptedAnswer"];
95
+ if (!answer?.["text"]) {
96
+ errors.push({
97
+ field: `mainEntity[${i}].acceptedAnswer.text`,
98
+ message: "FAQ answer is missing the \"text\" field",
99
+ severity: "error",
100
+ });
101
+ }
102
+ }
103
+ }
104
+ const hasErrors = errors.some((e) => e.severity === "error");
105
+ return { valid: !hasErrors, errors };
106
+ }
107
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ export interface SitemapEntry {
2
+ loc: string;
3
+ lastmod?: string;
4
+ changefreq?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
5
+ priority?: number;
6
+ }
7
+ export interface ImageSitemapEntry {
8
+ pageUrl: string;
9
+ images: Array<{
10
+ loc: string;
11
+ title?: string;
12
+ caption?: string;
13
+ geoLocation?: string;
14
+ license?: string;
15
+ }>;
16
+ }
17
+ export interface VideoSitemapEntry {
18
+ pageUrl: string;
19
+ video: {
20
+ thumbnailLoc: string;
21
+ title: string;
22
+ description: string;
23
+ contentLoc?: string;
24
+ playerLoc?: string;
25
+ duration?: number;
26
+ publicationDate?: string;
27
+ familyFriendly?: boolean;
28
+ };
29
+ }
30
+ export interface NewsSitemapEntry {
31
+ loc: string;
32
+ news: {
33
+ publicationName: string;
34
+ publicationLanguage: string;
35
+ publicationDate: string;
36
+ title: string;
37
+ keywords?: string[];
38
+ };
39
+ }
40
+ export interface HreflangEntry {
41
+ loc: string;
42
+ alternates: Array<{
43
+ hreflang: string;
44
+ href: string;
45
+ }>;
46
+ }
47
+ export interface CollectionSitemapConfig {
48
+ slug: string;
49
+ urlPrefix?: string;
50
+ type?: "page" | "post";
51
+ sitemapPriority?: number;
52
+ sitemapChangeFreq?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
53
+ excludeFromSitemap?: boolean;
54
+ archivePath?: string;
55
+ }
56
+ /**
57
+ * Build the public URL for a document given its collection config and slug.
58
+ * - Pages (urlPrefix: "") -> `{baseUrl}/{slug}`
59
+ * - Posts (urlPrefix: "blog") -> `{baseUrl}/blog/{slug}`
60
+ */
61
+ export declare function buildDocumentUrl(baseUrl: string, urlPrefix: string | undefined, slug: string): string;
62
+ /** Generates a sitemap index XML referencing per-collection sitemaps. */
63
+ export declare function generateSitemapIndex(collections: (string | CollectionSitemapConfig)[], baseUrl: string): string;
64
+ /**
65
+ * Generates a sitemap XML for a collection's documents.
66
+ * When `collectionConfig` is provided, document slugs are resolved to full URLs
67
+ * using the collection's `urlPrefix`. Archive pages are included for post-type collections.
68
+ */
69
+ export declare function generateCollectionSitemap(entries: SitemapEntry[], baseUrl: string, collectionConfig?: CollectionSitemapConfig): string;
70
+ /** Generates a Google Image sitemap extension. */
71
+ export declare function generateImageSitemap(entries: ImageSitemapEntry[]): string;
72
+ /** Generates a Google Video sitemap extension. */
73
+ export declare function generateVideoSitemap(entries: VideoSitemapEntry[]): string;
74
+ /** Generates a Google News sitemap. */
75
+ export declare function generateNewsSitemap(entries: NewsSitemapEntry[]): string;
76
+ /** Generates a sitemap with hreflang annotations for multilingual content. */
77
+ export declare function generateHreflangSitemap(entries: HreflangEntry[]): string;
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ function xmlEscape(str) {
2
+ return str
3
+ .replace(/&/g, "&amp;")
4
+ .replace(/</g, "&lt;")
5
+ .replace(/>/g, "&gt;")
6
+ .replace(/"/g, "&quot;")
7
+ .replace(/'/g, "&apos;");
8
+ }
9
+ /**
10
+ * Build the public URL for a document given its collection config and slug.
11
+ * - Pages (urlPrefix: "") -> `{baseUrl}/{slug}`
12
+ * - Posts (urlPrefix: "blog") -> `{baseUrl}/blog/{slug}`
13
+ */
14
+ export function buildDocumentUrl(baseUrl, urlPrefix, slug) {
15
+ const base = baseUrl.replace(/\/$/, "");
16
+ const prefix = urlPrefix ?? "";
17
+ if (prefix) {
18
+ return `${base}/${prefix}/${slug}`;
19
+ }
20
+ return `${base}/${slug}`;
21
+ }
22
+ /** Generates a sitemap index XML referencing per-collection sitemaps. */
23
+ export function generateSitemapIndex(collections, baseUrl) {
24
+ const base = baseUrl.replace(/\/$/, "");
25
+ const sitemaps = collections
26
+ .filter((col) => {
27
+ if (typeof col === "string")
28
+ return true;
29
+ return !col.excludeFromSitemap;
30
+ })
31
+ .map((col) => {
32
+ const slug = typeof col === "string" ? col : col.slug;
33
+ return ` <sitemap>\n <loc>${xmlEscape(base)}/sitemaps/${xmlEscape(slug)}.xml</loc>\n <lastmod>${new Date().toISOString()}</lastmod>\n </sitemap>`;
34
+ })
35
+ .join("\n");
36
+ return `<?xml version="1.0" encoding="UTF-8"?>
37
+ <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
38
+ ${sitemaps}
39
+ </sitemapindex>`;
40
+ }
41
+ /**
42
+ * Generates a sitemap XML for a collection's documents.
43
+ * When `collectionConfig` is provided, document slugs are resolved to full URLs
44
+ * using the collection's `urlPrefix`. Archive pages are included for post-type collections.
45
+ */
46
+ export function generateCollectionSitemap(entries, baseUrl, collectionConfig) {
47
+ const base = baseUrl.replace(/\/$/, "");
48
+ const allEntries = [...entries];
49
+ if (collectionConfig?.archivePath && collectionConfig.type === "post") {
50
+ allEntries.unshift({
51
+ loc: collectionConfig.archivePath,
52
+ changefreq: collectionConfig.sitemapChangeFreq ?? "weekly",
53
+ priority: 0.6,
54
+ });
55
+ }
56
+ const urls = allEntries
57
+ .map((entry) => {
58
+ let loc;
59
+ if (entry.loc.startsWith("http")) {
60
+ loc = entry.loc;
61
+ }
62
+ else if (entry.loc.startsWith("/")) {
63
+ loc = `${base}${entry.loc}`;
64
+ }
65
+ else if (collectionConfig) {
66
+ loc = buildDocumentUrl(base, collectionConfig.urlPrefix, entry.loc);
67
+ }
68
+ else {
69
+ loc = `${base}/${entry.loc}`;
70
+ }
71
+ const changefreq = entry.changefreq ?? collectionConfig?.sitemapChangeFreq;
72
+ const priority = entry.priority ?? collectionConfig?.sitemapPriority
73
+ ?? (collectionConfig?.type === "page" ? 0.8 : 0.6);
74
+ let xml = ` <url>\n <loc>${xmlEscape(loc)}</loc>`;
75
+ if (entry.lastmod)
76
+ xml += `\n <lastmod>${xmlEscape(entry.lastmod)}</lastmod>`;
77
+ if (changefreq)
78
+ xml += `\n <changefreq>${changefreq}</changefreq>`;
79
+ xml += `\n <priority>${priority.toFixed(1)}</priority>`;
80
+ xml += "\n </url>";
81
+ return xml;
82
+ })
83
+ .join("\n");
84
+ return `<?xml version="1.0" encoding="UTF-8"?>
85
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
86
+ ${urls}
87
+ </urlset>`;
88
+ }
89
+ /** Generates a Google Image sitemap extension. */
90
+ export function generateImageSitemap(entries) {
91
+ const urls = entries
92
+ .map((entry) => {
93
+ const images = entry.images
94
+ .map((img) => {
95
+ let xml = ` <image:image>\n <image:loc>${xmlEscape(img.loc)}</image:loc>`;
96
+ if (img.title)
97
+ xml += `\n <image:title>${xmlEscape(img.title)}</image:title>`;
98
+ if (img.caption)
99
+ xml += `\n <image:caption>${xmlEscape(img.caption)}</image:caption>`;
100
+ if (img.geoLocation)
101
+ xml += `\n <image:geo_location>${xmlEscape(img.geoLocation)}</image:geo_location>`;
102
+ if (img.license)
103
+ xml += `\n <image:license>${xmlEscape(img.license)}</image:license>`;
104
+ xml += "\n </image:image>";
105
+ return xml;
106
+ })
107
+ .join("\n");
108
+ return ` <url>\n <loc>${xmlEscape(entry.pageUrl)}</loc>\n${images}\n </url>`;
109
+ })
110
+ .join("\n");
111
+ return `<?xml version="1.0" encoding="UTF-8"?>
112
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
113
+ xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
114
+ ${urls}
115
+ </urlset>`;
116
+ }
117
+ /** Generates a Google Video sitemap extension. */
118
+ export function generateVideoSitemap(entries) {
119
+ const urls = entries
120
+ .map((entry) => {
121
+ const v = entry.video;
122
+ let xml = ` <url>\n <loc>${xmlEscape(entry.pageUrl)}</loc>\n <video:video>`;
123
+ xml += `\n <video:thumbnail_loc>${xmlEscape(v.thumbnailLoc)}</video:thumbnail_loc>`;
124
+ xml += `\n <video:title>${xmlEscape(v.title)}</video:title>`;
125
+ xml += `\n <video:description>${xmlEscape(v.description)}</video:description>`;
126
+ if (v.contentLoc)
127
+ xml += `\n <video:content_loc>${xmlEscape(v.contentLoc)}</video:content_loc>`;
128
+ if (v.playerLoc)
129
+ xml += `\n <video:player_loc>${xmlEscape(v.playerLoc)}</video:player_loc>`;
130
+ if (v.duration !== undefined)
131
+ xml += `\n <video:duration>${v.duration}</video:duration>`;
132
+ if (v.publicationDate)
133
+ xml += `\n <video:publication_date>${xmlEscape(v.publicationDate)}</video:publication_date>`;
134
+ if (v.familyFriendly !== undefined)
135
+ xml += `\n <video:family_friendly>${v.familyFriendly ? "yes" : "no"}</video:family_friendly>`;
136
+ xml += "\n </video:video>\n </url>";
137
+ return xml;
138
+ })
139
+ .join("\n");
140
+ return `<?xml version="1.0" encoding="UTF-8"?>
141
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
142
+ xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
143
+ ${urls}
144
+ </urlset>`;
145
+ }
146
+ /** Generates a Google News sitemap. */
147
+ export function generateNewsSitemap(entries) {
148
+ const urls = entries
149
+ .map((entry) => {
150
+ const n = entry.news;
151
+ let xml = ` <url>\n <loc>${xmlEscape(entry.loc)}</loc>\n <news:news>`;
152
+ xml += `\n <news:publication>`;
153
+ xml += `\n <news:name>${xmlEscape(n.publicationName)}</news:name>`;
154
+ xml += `\n <news:language>${xmlEscape(n.publicationLanguage)}</news:language>`;
155
+ xml += `\n </news:publication>`;
156
+ xml += `\n <news:publication_date>${xmlEscape(n.publicationDate)}</news:publication_date>`;
157
+ xml += `\n <news:title>${xmlEscape(n.title)}</news:title>`;
158
+ if (n.keywords?.length)
159
+ xml += `\n <news:keywords>${xmlEscape(n.keywords.join(", "))}</news:keywords>`;
160
+ xml += "\n </news:news>\n </url>";
161
+ return xml;
162
+ })
163
+ .join("\n");
164
+ return `<?xml version="1.0" encoding="UTF-8"?>
165
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
166
+ xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
167
+ ${urls}
168
+ </urlset>`;
169
+ }
170
+ /** Generates a sitemap with hreflang annotations for multilingual content. */
171
+ export function generateHreflangSitemap(entries) {
172
+ const urls = entries
173
+ .map((entry) => {
174
+ const links = entry.alternates
175
+ .map((alt) => ` <xhtml:link rel="alternate" hreflang="${xmlEscape(alt.hreflang)}" href="${xmlEscape(alt.href)}" />`)
176
+ .join("\n");
177
+ return ` <url>\n <loc>${xmlEscape(entry.loc)}</loc>\n${links}\n </url>`;
178
+ })
179
+ .join("\n");
180
+ return `<?xml version="1.0" encoding="UTF-8"?>
181
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
182
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
183
+ ${urls}
184
+ </urlset>`;
185
+ }
186
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@actuate-media/plugin-seo",
3
+ "version": "0.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/actuatecms/actuatecms.git",
7
+ "directory": "packages/plugin-seo"
8
+ },
9
+ "publishConfig": {
10
+ "access": "restricted"
11
+ },
12
+ "type": "module",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "files": ["dist"],
22
+ "scripts": {
23
+ "build": "tsc --project tsconfig.json",
24
+ "type-check": "tsc --noEmit",
25
+ "clean": "rm -rf dist .turbo"
26
+ },
27
+ "dependencies": {
28
+ "@actuate-media/cms-core": "workspace:*"
29
+ },
30
+ "devDependencies": {
31
+ "@types/react": "^19.0.0",
32
+ "typescript": "^5.7.0"
33
+ },
34
+ "peerDependencies": {
35
+ "react": "^19.2.0"
36
+ }
37
+ }