@growth-labs/seo 0.1.3

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 (158) hide show
  1. package/README.md +80 -0
  2. package/dist/index.d.ts +8 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +162 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/middleware/seo.d.ts +5 -0
  7. package/dist/middleware/seo.d.ts.map +1 -0
  8. package/dist/middleware/seo.js +70 -0
  9. package/dist/middleware/seo.js.map +1 -0
  10. package/dist/options.d.ts +489 -0
  11. package/dist/options.d.ts.map +1 -0
  12. package/dist/options.js +118 -0
  13. package/dist/options.js.map +1 -0
  14. package/dist/routes/llms.d.ts +4 -0
  15. package/dist/routes/llms.d.ts.map +1 -0
  16. package/dist/routes/llms.js +11 -0
  17. package/dist/routes/llms.js.map +1 -0
  18. package/dist/routes/podcast-narration.d.ts +4 -0
  19. package/dist/routes/podcast-narration.d.ts.map +1 -0
  20. package/dist/routes/podcast-narration.js +36 -0
  21. package/dist/routes/podcast-narration.js.map +1 -0
  22. package/dist/routes/podcast.d.ts +4 -0
  23. package/dist/routes/podcast.d.ts.map +1 -0
  24. package/dist/routes/podcast.js +20 -0
  25. package/dist/routes/podcast.js.map +1 -0
  26. package/dist/routes/robots.d.ts +4 -0
  27. package/dist/routes/robots.d.ts.map +1 -0
  28. package/dist/routes/robots.js +11 -0
  29. package/dist/routes/robots.js.map +1 -0
  30. package/dist/routes/rss.d.ts +4 -0
  31. package/dist/routes/rss.d.ts.map +1 -0
  32. package/dist/routes/rss.js +19 -0
  33. package/dist/routes/rss.js.map +1 -0
  34. package/dist/routes/sitemap-articles.d.ts +4 -0
  35. package/dist/routes/sitemap-articles.d.ts.map +1 -0
  36. package/dist/routes/sitemap-articles.js +19 -0
  37. package/dist/routes/sitemap-articles.js.map +1 -0
  38. package/dist/routes/sitemap-index.d.ts +4 -0
  39. package/dist/routes/sitemap-index.d.ts.map +1 -0
  40. package/dist/routes/sitemap-index.js +77 -0
  41. package/dist/routes/sitemap-index.js.map +1 -0
  42. package/dist/routes/sitemap-pages.d.ts +4 -0
  43. package/dist/routes/sitemap-pages.d.ts.map +1 -0
  44. package/dist/routes/sitemap-pages.js +18 -0
  45. package/dist/routes/sitemap-pages.js.map +1 -0
  46. package/dist/routes/sitemap-products.d.ts +4 -0
  47. package/dist/routes/sitemap-products.d.ts.map +1 -0
  48. package/dist/routes/sitemap-products.js +18 -0
  49. package/dist/routes/sitemap-products.js.map +1 -0
  50. package/dist/routes/sitemap-videos.d.ts +4 -0
  51. package/dist/routes/sitemap-videos.d.ts.map +1 -0
  52. package/dist/routes/sitemap-videos.js +18 -0
  53. package/dist/routes/sitemap-videos.js.map +1 -0
  54. package/dist/state.d.ts +7 -0
  55. package/dist/state.d.ts.map +1 -0
  56. package/dist/state.js +18 -0
  57. package/dist/state.js.map +1 -0
  58. package/dist/types.d.ts +103 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +2 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils/aeo.d.ts +16 -0
  63. package/dist/utils/aeo.d.ts.map +1 -0
  64. package/dist/utils/aeo.js +38 -0
  65. package/dist/utils/aeo.js.map +1 -0
  66. package/dist/utils/discover.d.ts +18 -0
  67. package/dist/utils/discover.d.ts.map +1 -0
  68. package/dist/utils/discover.js +41 -0
  69. package/dist/utils/discover.js.map +1 -0
  70. package/dist/utils/hreflang.d.ts +3 -0
  71. package/dist/utils/hreflang.d.ts.map +1 -0
  72. package/dist/utils/hreflang.js +20 -0
  73. package/dist/utils/hreflang.js.map +1 -0
  74. package/dist/utils/index.d.ts +12 -0
  75. package/dist/utils/index.d.ts.map +1 -0
  76. package/dist/utils/index.js +12 -0
  77. package/dist/utils/index.js.map +1 -0
  78. package/dist/utils/json-ld/article.d.ts +4 -0
  79. package/dist/utils/json-ld/article.d.ts.map +1 -0
  80. package/dist/utils/json-ld/article.js +66 -0
  81. package/dist/utils/json-ld/article.js.map +1 -0
  82. package/dist/utils/json-ld/audio.d.ts +7 -0
  83. package/dist/utils/json-ld/audio.d.ts.map +1 -0
  84. package/dist/utils/json-ld/audio.js +25 -0
  85. package/dist/utils/json-ld/audio.js.map +1 -0
  86. package/dist/utils/json-ld/breadcrumb.d.ts +7 -0
  87. package/dist/utils/json-ld/breadcrumb.d.ts.map +1 -0
  88. package/dist/utils/json-ld/breadcrumb.js +20 -0
  89. package/dist/utils/json-ld/breadcrumb.js.map +1 -0
  90. package/dist/utils/json-ld/faq.d.ts +6 -0
  91. package/dist/utils/json-ld/faq.d.ts.map +1 -0
  92. package/dist/utils/json-ld/faq.js +15 -0
  93. package/dist/utils/json-ld/faq.js.map +1 -0
  94. package/dist/utils/json-ld/howto.d.ts +7 -0
  95. package/dist/utils/json-ld/howto.d.ts.map +1 -0
  96. package/dist/utils/json-ld/howto.js +19 -0
  97. package/dist/utils/json-ld/howto.js.map +1 -0
  98. package/dist/utils/json-ld/index.d.ts +13 -0
  99. package/dist/utils/json-ld/index.d.ts.map +1 -0
  100. package/dist/utils/json-ld/index.js +12 -0
  101. package/dist/utils/json-ld/index.js.map +1 -0
  102. package/dist/utils/json-ld/item-list.d.ts +5 -0
  103. package/dist/utils/json-ld/item-list.d.ts.map +1 -0
  104. package/dist/utils/json-ld/item-list.js +20 -0
  105. package/dist/utils/json-ld/item-list.js.map +1 -0
  106. package/dist/utils/json-ld/organization.d.ts +4 -0
  107. package/dist/utils/json-ld/organization.d.ts.map +1 -0
  108. package/dist/utils/json-ld/organization.js +36 -0
  109. package/dist/utils/json-ld/organization.js.map +1 -0
  110. package/dist/utils/json-ld/person.d.ts +6 -0
  111. package/dist/utils/json-ld/person.d.ts.map +1 -0
  112. package/dist/utils/json-ld/person.js +23 -0
  113. package/dist/utils/json-ld/person.js.map +1 -0
  114. package/dist/utils/json-ld/product.d.ts +5 -0
  115. package/dist/utils/json-ld/product.d.ts.map +1 -0
  116. package/dist/utils/json-ld/product.js +112 -0
  117. package/dist/utils/json-ld/product.js.map +1 -0
  118. package/dist/utils/json-ld/video.d.ts +3 -0
  119. package/dist/utils/json-ld/video.d.ts.map +1 -0
  120. package/dist/utils/json-ld/video.js +20 -0
  121. package/dist/utils/json-ld/video.js.map +1 -0
  122. package/dist/utils/json-ld/website.d.ts +4 -0
  123. package/dist/utils/json-ld/website.d.ts.map +1 -0
  124. package/dist/utils/json-ld/website.js +22 -0
  125. package/dist/utils/json-ld/website.js.map +1 -0
  126. package/dist/utils/llms.d.ts +7 -0
  127. package/dist/utils/llms.d.ts.map +1 -0
  128. package/dist/utils/llms.js +38 -0
  129. package/dist/utils/llms.js.map +1 -0
  130. package/dist/utils/meta.d.ts +7 -0
  131. package/dist/utils/meta.d.ts.map +1 -0
  132. package/dist/utils/meta.js +122 -0
  133. package/dist/utils/meta.js.map +1 -0
  134. package/dist/utils/podcast.d.ts +8 -0
  135. package/dist/utils/podcast.d.ts.map +1 -0
  136. package/dist/utils/podcast.js +94 -0
  137. package/dist/utils/podcast.js.map +1 -0
  138. package/dist/utils/robots.d.ts +3 -0
  139. package/dist/utils/robots.d.ts.map +1 -0
  140. package/dist/utils/robots.js +28 -0
  141. package/dist/utils/robots.js.map +1 -0
  142. package/dist/utils/rss.d.ts +4 -0
  143. package/dist/utils/rss.d.ts.map +1 -0
  144. package/dist/utils/rss.js +53 -0
  145. package/dist/utils/rss.js.map +1 -0
  146. package/dist/utils/sitemap.d.ts +13 -0
  147. package/dist/utils/sitemap.d.ts.map +1 -0
  148. package/dist/utils/sitemap.js +133 -0
  149. package/dist/utils/sitemap.js.map +1 -0
  150. package/dist/utils/validation.d.ts +18 -0
  151. package/dist/utils/validation.d.ts.map +1 -0
  152. package/dist/utils/validation.js +141 -0
  153. package/dist/utils/validation.js.map +1 -0
  154. package/dist/vite-plugin.d.ts +4 -0
  155. package/dist/vite-plugin.d.ts.map +1 -0
  156. package/dist/vite-plugin.js +22 -0
  157. package/dist/vite-plugin.js.map +1 -0
  158. package/package.json +59 -0
@@ -0,0 +1,36 @@
1
+ import { getConfig, getContentProvider } from '../state.js';
2
+ import { generatePodcastFeed } from '../utils/podcast.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const config = getConfig();
6
+ const contentProvider = getContentProvider();
7
+ let articles = [];
8
+ if (contentProvider) {
9
+ try {
10
+ articles = await contentProvider({ type: 'articles' }, context);
11
+ }
12
+ catch { }
13
+ }
14
+ const withAudio = articles.filter((a) => a.audio);
15
+ const narrationPodcastConfig = {
16
+ ...config,
17
+ podcast: {
18
+ enabled: true,
19
+ title: `${config.organization.name} — Listen`,
20
+ description: `Narrated articles from ${config.organization.name}`,
21
+ author: config.audioNarration?.narratorName ?? config.organization.name,
22
+ email: '',
23
+ image: config.organization.logo,
24
+ category: 'News',
25
+ language: config.defaults.locale.split('_')[0] ?? 'en',
26
+ explicit: false,
27
+ feedPath: config.audioNarration?.podcastFeedPath ?? '/listen.xml',
28
+ type: 'episodic',
29
+ },
30
+ };
31
+ const xml = generatePodcastFeed(withAudio, narrationPodcastConfig);
32
+ return new Response(xml, {
33
+ headers: { 'Content-Type': 'application/rss+xml; charset=utf-8' },
34
+ });
35
+ };
36
+ //# sourceMappingURL=podcast-narration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcast-narration.js","sourceRoot":"","sources":["../../src/routes/podcast-narration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,QAAQ,GAAkB,EAAE,CAAA;IAChC,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAc,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAEjD,MAAM,sBAAsB,GAAG;QAC9B,GAAG,MAAM;QACT,OAAO,EAAE;YACR,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,WAAW;YAC7C,WAAW,EAAE,0BAA0B,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;YACjE,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI;YACvE,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI;YAC/B,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtD,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,eAAe,IAAI,aAAa;YACjE,IAAI,EAAE,UAAmB;SACzB;KACD,CAAA;IAED,MAAM,GAAG,GAAG,mBAAmB,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAA;IAElE,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,oCAAoC,EAAE;KACjE,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=podcast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcast.d.ts","sourceRoot":"","sources":["../../src/routes/podcast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAiBjB,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { getConfig, getContentProvider } from '../state.js';
2
+ import { generatePodcastFeed } from '../utils/podcast.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const config = getConfig();
6
+ const contentProvider = getContentProvider();
7
+ let articles = [];
8
+ if (contentProvider) {
9
+ try {
10
+ articles = await contentProvider({ type: 'articles' }, context);
11
+ }
12
+ catch { }
13
+ }
14
+ const withAudio = articles.filter((a) => a.audio);
15
+ const xml = generatePodcastFeed(withAudio, config);
16
+ return new Response(xml, {
17
+ headers: { 'Content-Type': 'application/rss+xml; charset=utf-8' },
18
+ });
19
+ };
20
+ //# sourceMappingURL=podcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcast.js","sourceRoot":"","sources":["../../src/routes/podcast.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,QAAQ,GAAkB,EAAE,CAAA;IAChC,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAc,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,GAAG,GAAG,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAElD,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,oCAAoC,EAAE;KACjE,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=robots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/routes/robots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAIrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAOjB,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { getConfig } from '../state.js';
2
+ import { generateRobotsTxt } from '../utils/robots.js';
3
+ export const prerender = false;
4
+ export const GET = async () => {
5
+ const config = getConfig();
6
+ const txt = generateRobotsTxt(config);
7
+ return new Response(txt, {
8
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
9
+ });
10
+ };
11
+ //# sourceMappingURL=robots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"robots.js","sourceRoot":"","sources":["../../src/routes/robots.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,IAAI,EAAE;IACvC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;IAErC,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE;KACxD,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=rss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rss.d.ts","sourceRoot":"","sources":["../../src/routes/rss.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAgBjB,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { getConfig, getContentProvider } from '../state.js';
2
+ import { generateRssFeed } from '../utils/rss.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const config = getConfig();
6
+ const contentProvider = getContentProvider();
7
+ let articles = [];
8
+ if (contentProvider) {
9
+ try {
10
+ articles = await contentProvider({ type: 'articles' }, context);
11
+ }
12
+ catch { }
13
+ }
14
+ const xml = generateRssFeed(articles, config);
15
+ return new Response(xml, {
16
+ headers: { 'Content-Type': 'application/rss+xml; charset=utf-8' },
17
+ });
18
+ };
19
+ //# sourceMappingURL=rss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rss.js","sourceRoot":"","sources":["../../src/routes/rss.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,QAAQ,GAAkB,EAAE,CAAA;IAChC,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAc,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAE7C,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,oCAAoC,EAAE;KACjE,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=sitemap-articles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-articles.d.ts","sourceRoot":"","sources":["../../src/routes/sitemap-articles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAgBjB,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { getConfig, getContentProvider } from '../state.js';
2
+ import { generateArticleSitemap } from '../utils/sitemap.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const config = getConfig();
6
+ const contentProvider = getContentProvider();
7
+ let articles = [];
8
+ if (contentProvider) {
9
+ try {
10
+ articles = await contentProvider({ type: 'articles' }, context);
11
+ }
12
+ catch { }
13
+ }
14
+ const xml = generateArticleSitemap(articles, config);
15
+ return new Response(xml, {
16
+ headers: { 'Content-Type': 'application/xml; charset=utf-8' },
17
+ });
18
+ };
19
+ //# sourceMappingURL=sitemap-articles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-articles.js","sourceRoot":"","sources":["../../src/routes/sitemap-articles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,QAAQ,GAAkB,EAAE,CAAA;IAChC,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAc,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAEpD,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,gCAAgC,EAAE;KAC7D,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=sitemap-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-index.d.ts","sourceRoot":"","sources":["../../src/routes/sitemap-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QA+EjB,CAAA"}
@@ -0,0 +1,77 @@
1
+ import { getConfig, getContentProvider } from '../state.js';
2
+ import { generateSitemapIndex } from '../utils/sitemap.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const config = getConfig();
6
+ const contentProvider = getContentProvider();
7
+ const sitemaps = [];
8
+ const { site } = config;
9
+ // Fetch articles lastmod if possible
10
+ let articlesLastmod;
11
+ let pagesLastmod;
12
+ let videosLastmod;
13
+ let productsLastmod;
14
+ if (contentProvider) {
15
+ try {
16
+ const articles = await contentProvider({ type: 'articles' }, context);
17
+ if (articles.length > 0) {
18
+ const dates = articles
19
+ .map((a) => a.dateModified ?? a.datePublished)
20
+ .filter(Boolean);
21
+ if (dates.length > 0) {
22
+ articlesLastmod = dates.sort().at(-1);
23
+ }
24
+ }
25
+ }
26
+ catch { }
27
+ try {
28
+ const pages = await contentProvider({ type: 'pages' }, context);
29
+ if (pages.length > 0) {
30
+ const dates = pages
31
+ .map((p) => p.dateModified ?? p.datePublished)
32
+ .filter(Boolean);
33
+ if (dates.length > 0) {
34
+ pagesLastmod = dates.sort().at(-1);
35
+ }
36
+ }
37
+ }
38
+ catch { }
39
+ try {
40
+ const videos = await contentProvider({ type: 'videos' }, context);
41
+ if (videos.length > 0) {
42
+ const dates = videos
43
+ .map((v) => v.dateModified ?? v.datePublished)
44
+ .filter(Boolean);
45
+ if (dates.length > 0) {
46
+ videosLastmod = dates.sort().at(-1);
47
+ }
48
+ }
49
+ }
50
+ catch { }
51
+ if (config.commerce?.enabled) {
52
+ try {
53
+ const products = await contentProvider({ type: 'products' }, context);
54
+ if (products.length > 0) {
55
+ const dates = products
56
+ .map((p) => p.dateModified ?? p.datePublished)
57
+ .filter(Boolean);
58
+ if (dates.length > 0) {
59
+ productsLastmod = dates.sort().at(-1);
60
+ }
61
+ }
62
+ }
63
+ catch { }
64
+ }
65
+ }
66
+ sitemaps.push({ loc: `${site}/sitemap-articles.xml`, lastmod: articlesLastmod });
67
+ sitemaps.push({ loc: `${site}/sitemap-pages.xml`, lastmod: pagesLastmod });
68
+ sitemaps.push({ loc: `${site}/sitemap-videos.xml`, lastmod: videosLastmod });
69
+ if (config.commerce?.enabled) {
70
+ sitemaps.push({ loc: `${site}/sitemap-products.xml`, lastmod: productsLastmod });
71
+ }
72
+ const xml = generateSitemapIndex(sitemaps);
73
+ return new Response(xml, {
74
+ headers: { 'Content-Type': 'application/xml; charset=utf-8' },
75
+ });
76
+ };
77
+ //# sourceMappingURL=sitemap-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-index.js","sourceRoot":"","sources":["../../src/routes/sitemap-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=sitemap-pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-pages.d.ts","sourceRoot":"","sources":["../../src/routes/sitemap-pages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAejB,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { getContentProvider } from '../state.js';
2
+ import { generatePagesSitemap } from '../utils/sitemap.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const contentProvider = getContentProvider();
6
+ let pages = [];
7
+ if (contentProvider) {
8
+ try {
9
+ pages = await contentProvider({ type: 'pages' }, context);
10
+ }
11
+ catch { }
12
+ }
13
+ const xml = generatePagesSitemap(pages);
14
+ return new Response(xml, {
15
+ headers: { 'Content-Type': 'application/xml; charset=utf-8' },
16
+ });
17
+ };
18
+ //# sourceMappingURL=sitemap-pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-pages.js","sourceRoot":"","sources":["../../src/routes/sitemap-pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,KAAK,GAAkB,EAAE,CAAA;IAC7B,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,KAAK,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAc,CAAC,CAAA;QACjE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAEvC,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,gCAAgC,EAAE;KAC7D,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=sitemap-products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-products.d.ts","sourceRoot":"","sources":["../../src/routes/sitemap-products.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAejB,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { getContentProvider } from '../state.js';
2
+ import { generateProductSitemap } from '../utils/sitemap.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const contentProvider = getContentProvider();
6
+ let products = [];
7
+ if (contentProvider) {
8
+ try {
9
+ products = await contentProvider({ type: 'products' }, context);
10
+ }
11
+ catch { }
12
+ }
13
+ const xml = generateProductSitemap(products);
14
+ return new Response(xml, {
15
+ headers: { 'Content-Type': 'application/xml; charset=utf-8' },
16
+ });
17
+ };
18
+ //# sourceMappingURL=sitemap-products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-products.js","sourceRoot":"","sources":["../../src/routes/sitemap-products.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,QAAQ,GAAkB,EAAE,CAAA;IAChC,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAc,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IAE5C,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,gCAAgC,EAAE;KAC7D,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { APIRoute } from 'astro';
2
+ export declare const prerender = false;
3
+ export declare const GET: APIRoute;
4
+ //# sourceMappingURL=sitemap-videos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-videos.d.ts","sourceRoot":"","sources":["../../src/routes/sitemap-videos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAKrC,eAAO,MAAM,SAAS,QAAQ,CAAA;AAE9B,eAAO,MAAM,GAAG,EAAE,QAejB,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { getContentProvider } from '../state.js';
2
+ import { generateVideoSitemap } from '../utils/sitemap.js';
3
+ export const prerender = false;
4
+ export const GET = async (context) => {
5
+ const contentProvider = getContentProvider();
6
+ let videos = [];
7
+ if (contentProvider) {
8
+ try {
9
+ videos = await contentProvider({ type: 'videos' }, context);
10
+ }
11
+ catch { }
12
+ }
13
+ const xml = generateVideoSitemap(videos);
14
+ return new Response(xml, {
15
+ headers: { 'Content-Type': 'application/xml; charset=utf-8' },
16
+ });
17
+ };
18
+ //# sourceMappingURL=sitemap-videos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap-videos.js","sourceRoot":"","sources":["../../src/routes/sitemap-videos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAA;AAE9B,MAAM,CAAC,MAAM,GAAG,GAAa,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9C,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAE5C,IAAI,MAAM,GAAkB,EAAE,CAAA;IAC9B,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAc,CAAC,CAAA;QACnE,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAExC,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,gCAAgC,EAAE;KAC7D,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { ResolvedSeoOptions } from './options.js';
2
+ import type { ContentProvider } from './types.js';
3
+ export declare function _setConfig(config: ResolvedSeoOptions): void;
4
+ export declare function _setContentProvider(provider: ContentProvider): void;
5
+ export declare function getConfig(): ResolvedSeoOptions;
6
+ export declare function getContentProvider(): ContentProvider | undefined;
7
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAKjD,wBAAgB,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAE3D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAEnE;AAED,wBAAgB,SAAS,IAAI,kBAAkB,CAO9C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,SAAS,CAEhE"}
package/dist/state.js ADDED
@@ -0,0 +1,18 @@
1
+ let _config = null;
2
+ let _contentProvider;
3
+ export function _setConfig(config) {
4
+ _config = config;
5
+ }
6
+ export function _setContentProvider(provider) {
7
+ _contentProvider = provider;
8
+ }
9
+ export function getConfig() {
10
+ if (!_config) {
11
+ throw new Error('@growth-labs/seo: integration not initialized. Ensure seo() is added to your Astro config.');
12
+ }
13
+ return _config;
14
+ }
15
+ export function getContentProvider() {
16
+ return _contentProvider;
17
+ }
18
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAGA,IAAI,OAAO,GAA8B,IAAI,CAAA;AAC7C,IAAI,gBAA6C,CAAA;AAEjD,MAAM,UAAU,UAAU,CAAC,MAA0B;IACpD,OAAO,GAAG,MAAM,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAyB;IAC5D,gBAAgB,GAAG,QAAQ,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS;IACxB,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACd,4FAA4F,CAC5F,CAAA;IACF,CAAC;IACD,OAAO,OAAO,CAAA;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB;IACjC,OAAO,gBAAgB,CAAA;AACxB,CAAC"}
@@ -0,0 +1,103 @@
1
+ import type { APIContext } from 'astro';
2
+ export interface ContentAuthor {
3
+ name: string;
4
+ url?: string;
5
+ jobTitle?: string;
6
+ sameAs?: string[];
7
+ }
8
+ export interface ContentAudio {
9
+ url: string;
10
+ duration: string;
11
+ narrator?: string;
12
+ }
13
+ export interface ContentLocaleAlternate {
14
+ lang: string;
15
+ url: string;
16
+ }
17
+ export interface ProductVariant {
18
+ name: string;
19
+ sku?: string;
20
+ price: number;
21
+ currency?: string;
22
+ availability: 'InStock' | 'OutOfStock' | 'PreOrder' | 'Discontinued';
23
+ image?: string;
24
+ }
25
+ export interface ContentProduct {
26
+ name: string;
27
+ description: string;
28
+ price: number;
29
+ currency: string;
30
+ availability: 'InStock' | 'OutOfStock' | 'PreOrder' | 'Discontinued';
31
+ brand?: string;
32
+ sku?: string;
33
+ gtin?: string;
34
+ mpn?: string;
35
+ images: string[];
36
+ rating?: {
37
+ value: number;
38
+ count: number;
39
+ bestRating?: number;
40
+ };
41
+ reviews?: Array<{
42
+ author: string;
43
+ rating: number;
44
+ body?: string;
45
+ datePublished?: string;
46
+ }>;
47
+ variants?: ProductVariant[];
48
+ condition?: 'NewCondition' | 'UsedCondition' | 'RefurbishedCondition';
49
+ }
50
+ export interface PodcastEpisodeMeta {
51
+ episodeNumber?: number;
52
+ seasonNumber?: number;
53
+ episodeType?: 'full' | 'trailer' | 'bonus';
54
+ }
55
+ export interface ContentItem {
56
+ url: string;
57
+ title: string;
58
+ description?: string;
59
+ image?: string;
60
+ datePublished?: string;
61
+ dateModified?: string;
62
+ authors?: ContentAuthor[];
63
+ audio?: ContentAudio;
64
+ podcastEpisode?: PodcastEpisodeMeta;
65
+ locale?: string;
66
+ alternateLocales?: ContentLocaleAlternate[];
67
+ isAccessibleForFree?: boolean;
68
+ paywallCssSelector?: string;
69
+ product?: ContentProduct;
70
+ faq?: Array<{
71
+ question: string;
72
+ answer: string;
73
+ }>;
74
+ howToSteps?: Array<{
75
+ name: string;
76
+ text: string;
77
+ image?: string;
78
+ }>;
79
+ video?: {
80
+ thumbnailUrl: string;
81
+ duration: string;
82
+ contentUrl?: string;
83
+ embedUrl?: string;
84
+ };
85
+ }
86
+ export type ContentType = 'articles' | 'pages' | 'videos' | 'products' | 'authors';
87
+ export type ContentProvider = (params: {
88
+ type: ContentType;
89
+ }, context: APIContext) => Promise<ContentItem[]>;
90
+ export interface MetaTag {
91
+ [key: string]: string;
92
+ }
93
+ export interface CanonicalLink {
94
+ rel: 'canonical';
95
+ href: string;
96
+ }
97
+ export interface HreflangLink {
98
+ rel: 'alternate';
99
+ hreflang: string;
100
+ href: string;
101
+ }
102
+ export type JsonLdObject = Record<string, unknown>;
103
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AEO (Answer Engine Optimization) utilities
3
+ * Generates AI-friendly markdown with YAML frontmatter
4
+ */
5
+ export declare function estimateTokenCount(text: string): number;
6
+ export declare function generateAeoMarkdown(item: {
7
+ url: string;
8
+ title: string;
9
+ description?: string;
10
+ datePublished?: string;
11
+ dateModified?: string;
12
+ authors?: Array<{
13
+ name: string;
14
+ }>;
15
+ }, content: string, schemaType: string, publisherName: string): string;
16
+ //# sourceMappingURL=aeo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeo.d.ts","sourceRoot":"","sources":["../../src/utils/aeo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE;IACL,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACjC,EACD,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACnB,MAAM,CA8BR"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * AEO (Answer Engine Optimization) utilities
3
+ * Generates AI-friendly markdown with YAML frontmatter
4
+ */
5
+ export function estimateTokenCount(text) {
6
+ return Math.ceil(text.length / 4);
7
+ }
8
+ export function generateAeoMarkdown(item, content, schemaType, publisherName) {
9
+ const frontmatter = {
10
+ title: item.title,
11
+ url: item.url,
12
+ schemaType,
13
+ publisher: publisherName,
14
+ };
15
+ if (item.description)
16
+ frontmatter.description = item.description;
17
+ if (item.datePublished)
18
+ frontmatter.datePublished = item.datePublished;
19
+ if (item.dateModified)
20
+ frontmatter.dateModified = item.dateModified;
21
+ if (item.authors?.length) {
22
+ frontmatter.authors = item.authors.map((a) => a.name);
23
+ }
24
+ const yamlLines = Object.entries(frontmatter).map(([key, value]) => {
25
+ if (Array.isArray(value)) {
26
+ return `${key}:\n${value.map((v) => ` - ${v}`).join('\n')}`;
27
+ }
28
+ // Wrap in quotes only when truly needed for YAML validity
29
+ // URLs with :// are fine unquoted; dates with colons need quoting if they'd be ambiguous
30
+ const str = String(value);
31
+ const isUrl = /^https?:\/\//.test(str);
32
+ const isDate = /^\d{4}-\d{2}-\d{2}/.test(str);
33
+ const hasYamlSpecial = /[#[\]{},&*?|>'"!%@`]/.test(str) || (!isUrl && !isDate && str.includes(':'));
34
+ return `${key}: ${hasYamlSpecial ? `"${str.replace(/"/g, '\\"')}"` : str}`;
35
+ });
36
+ return `---\n${yamlLines.join('\n')}\n---\n\n${content}`;
37
+ }
38
+ //# sourceMappingURL=aeo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeo.js","sourceRoot":"","sources":["../../src/utils/aeo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,IAOC,EACD,OAAe,EACf,UAAkB,EAClB,aAAqB;IAErB,MAAM,WAAW,GAAsC;QACtD,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,UAAU;QACV,SAAS,EAAE,aAAa;KACxB,CAAA;IAED,IAAI,IAAI,CAAC,WAAW;QAAE,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;IAChE,IAAI,IAAI,CAAC,aAAa;QAAE,WAAW,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAA;IACtE,IAAI,IAAI,CAAC,YAAY;QAAE,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;IACnE,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC1B,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAClE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAC7D,CAAC;QACD,0DAA0D;QAC1D,yFAAyF;QACzF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QACzB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC7C,MAAM,cAAc,GACnB,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;QAC7E,OAAO,GAAG,GAAG,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,OAAO,QAAQ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAA;AACzD,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface DiscoverImage {
2
+ '@type': 'ImageObject';
3
+ url: string;
4
+ width: number;
5
+ height: number;
6
+ }
7
+ export declare function buildDiscoverImageUrls(imageUrl: string, site: string): string[];
8
+ /**
9
+ * Returns three ImageObject entries for Google Discover optimization.
10
+ * Google Discover requires images in 16:9, 4:3, and 1:1 aspect ratios,
11
+ * each at least 1200px wide.
12
+ *
13
+ * Consumers should supply the actual image URLs (typically generated via
14
+ * @growth-labs/media image transformations). This utility wraps them in
15
+ * schema.org ImageObject format suitable for JSON-LD `image` arrays.
16
+ */
17
+ export declare function getDiscoverImages(imageUrl16x9: string, imageUrl4x3: string, imageUrl1x1: string): DiscoverImage[];
18
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/utils/discover.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,aAAa,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACd;AAQD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAO/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAChC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GACjB,aAAa,EAAE,CAqBjB"}