@uptrademedia/site-kit 1.1.7 → 1.2.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 (113) hide show
  1. package/dist/analytics/index.d.mts +2 -2
  2. package/dist/analytics/index.d.ts +2 -2
  3. package/dist/analytics/index.js +6 -6
  4. package/dist/analytics/index.mjs +2 -2
  5. package/dist/{api-l44k92vp.d.mts → api-CWtoFJCO.d.mts} +1 -1
  6. package/dist/{api-l44k92vp.d.ts → api-CWtoFJCO.d.ts} +1 -1
  7. package/dist/blog/index.d.mts +2 -2
  8. package/dist/blog/index.d.ts +2 -2
  9. package/dist/blog/server.d.mts +1 -1
  10. package/dist/blog/server.d.ts +1 -1
  11. package/dist/{chunk-HEUULOSC.js → chunk-2MNLOYDD.js} +3 -3
  12. package/dist/{chunk-HEUULOSC.js.map → chunk-2MNLOYDD.js.map} +1 -1
  13. package/dist/{chunk-LHMD7CAR.mjs → chunk-2STSAGNT.mjs} +28 -6
  14. package/dist/chunk-2STSAGNT.mjs.map +1 -0
  15. package/dist/{chunk-3LOFIO77.mjs → chunk-44OMJFCG.mjs} +187 -193
  16. package/dist/chunk-44OMJFCG.mjs.map +1 -0
  17. package/dist/{chunk-CTKXFLIF.js → chunk-47ZS7MKZ.js} +119 -80
  18. package/dist/chunk-47ZS7MKZ.js.map +1 -0
  19. package/dist/{chunk-VFJ3NNCY.js → chunk-DERI27QC.js} +187 -193
  20. package/dist/chunk-DERI27QC.js.map +1 -0
  21. package/dist/{chunk-TOUIKTXU.mjs → chunk-FHTQUJ4M.mjs} +118 -80
  22. package/dist/chunk-FHTQUJ4M.mjs.map +1 -0
  23. package/dist/{chunk-IRNMIFOE.js → chunk-ICHCPLRB.js} +28 -6
  24. package/dist/chunk-ICHCPLRB.js.map +1 -0
  25. package/dist/{chunk-HGTTGJVZ.js → chunk-LBHEVL6U.js} +3 -3
  26. package/dist/{chunk-HGTTGJVZ.js.map → chunk-LBHEVL6U.js.map} +1 -1
  27. package/dist/{chunk-YT5SBY5W.mjs → chunk-MLJXNFUO.mjs} +3 -3
  28. package/dist/{chunk-YT5SBY5W.mjs.map → chunk-MLJXNFUO.mjs.map} +1 -1
  29. package/dist/{chunk-OW2C3ATV.mjs → chunk-R6V7DQ24.mjs} +3 -3
  30. package/dist/{chunk-OW2C3ATV.mjs.map → chunk-R6V7DQ24.mjs.map} +1 -1
  31. package/dist/cli/index.js +831 -740
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/index.mjs +825 -734
  34. package/dist/cli/index.mjs.map +1 -1
  35. package/dist/commerce/index.d.mts +3 -3
  36. package/dist/commerce/index.d.ts +3 -3
  37. package/dist/commerce/server.d.mts +1 -1
  38. package/dist/commerce/server.d.ts +1 -1
  39. package/dist/engage/index.d.mts +2 -2
  40. package/dist/engage/index.d.ts +2 -2
  41. package/dist/engage/index.js +4 -4
  42. package/dist/engage/index.mjs +1 -1
  43. package/dist/images/index.d.mts +1 -1
  44. package/dist/images/index.d.ts +1 -1
  45. package/dist/index.d.mts +7 -7
  46. package/dist/index.d.ts +7 -7
  47. package/dist/index.js +4 -4
  48. package/dist/index.mjs +2 -2
  49. package/dist/llms/index.d.mts +23 -274
  50. package/dist/llms/index.d.ts +23 -274
  51. package/dist/llms/index.js +14 -14
  52. package/dist/llms/index.js.map +1 -1
  53. package/dist/llms/index.mjs +4 -4
  54. package/dist/llms/index.mjs.map +1 -1
  55. package/dist/robots/index.d.mts +46 -0
  56. package/dist/robots/index.d.ts +46 -0
  57. package/dist/robots/index.js +34 -0
  58. package/dist/robots/index.js.map +1 -0
  59. package/dist/robots/index.mjs +32 -0
  60. package/dist/robots/index.mjs.map +1 -0
  61. package/dist/{routing-D311WhuV.d.ts → routing-BI69sU8F.d.ts} +1 -1
  62. package/dist/{routing-bTjqOM8S.d.mts → routing-Bg1nr9N0.d.mts} +1 -1
  63. package/dist/{scanner-VNEXRTZF.mjs → scanner-7ZMUM2P5.mjs} +3 -3
  64. package/dist/{scanner-VNEXRTZF.mjs.map → scanner-7ZMUM2P5.mjs.map} +1 -1
  65. package/dist/{scanner-CVKYTPUO.js → scanner-OY7UF3WA.js} +14 -14
  66. package/dist/{scanner-CVKYTPUO.js.map → scanner-OY7UF3WA.js.map} +1 -1
  67. package/dist/seo/index.d.mts +3 -3
  68. package/dist/seo/index.d.ts +3 -3
  69. package/dist/seo/server.d.mts +2 -2
  70. package/dist/seo/server.d.ts +2 -2
  71. package/dist/setup/index.js +2 -2
  72. package/dist/setup/index.mjs +1 -1
  73. package/dist/setup/server.js +2 -2
  74. package/dist/setup/server.mjs +1 -1
  75. package/dist/sitemap/index.d.mts +5 -1
  76. package/dist/sitemap/index.d.ts +5 -1
  77. package/dist/sitemap/index.js +5 -4
  78. package/dist/sitemap/index.js.map +1 -1
  79. package/dist/sitemap/index.mjs +4 -3
  80. package/dist/sitemap/index.mjs.map +1 -1
  81. package/dist/{socket-loader-3FWQWPDQ.js → socket-loader-J26QHHOB.js} +2 -2
  82. package/dist/socket-loader-J26QHHOB.js.map +1 -0
  83. package/dist/{socket-loader-N5ETWMXW.mjs → socket-loader-R7S2YJ2J.mjs} +2 -2
  84. package/dist/socket-loader-R7S2YJ2J.mjs.map +1 -0
  85. package/dist/{types-C_pfGZhI.d.mts → types-Bsf5kX1n.d.mts} +1 -1
  86. package/dist/{types-C_pfGZhI.d.ts → types-Bsf5kX1n.d.ts} +1 -1
  87. package/dist/{types-DxhEH2tX.d.mts → types-CNZcDIoX.d.mts} +1 -1
  88. package/dist/{types-DxhEH2tX.d.ts → types-CNZcDIoX.d.ts} +1 -1
  89. package/dist/types-D8i7Alvv.d.mts +259 -0
  90. package/dist/types-D8i7Alvv.d.ts +259 -0
  91. package/dist/{types-DiZVgJKD.d.mts → types-DA_Kocle.d.mts} +1 -1
  92. package/dist/{types-DiZVgJKD.d.ts → types-DA_Kocle.d.ts} +1 -1
  93. package/dist/{types-CMNYdZwT.d.mts → types-DI0jnhjJ.d.mts} +1 -1
  94. package/dist/{types-CMNYdZwT.d.ts → types-DI0jnhjJ.d.ts} +1 -1
  95. package/dist/{types-BF2v5qX3.d.mts → types-wCtRFR0Y.d.mts} +1 -1
  96. package/dist/{types-BF2v5qX3.d.ts → types-wCtRFR0Y.d.ts} +1 -1
  97. package/dist/{useEventModal-x_RZRewW.d.mts → useEventModal-Bs0W9Iy_.d.mts} +2 -2
  98. package/dist/{useEventModal-5fIKdIaY.d.ts → useEventModal-Btu3uIjE.d.ts} +2 -2
  99. package/dist/{web-vitals-PW6MQOKS.js → web-vitals-444RLW3B.js} +3 -3
  100. package/dist/web-vitals-444RLW3B.js.map +1 -0
  101. package/dist/{web-vitals-YSIFBTH7.mjs → web-vitals-KPICZIEF.mjs} +3 -3
  102. package/dist/web-vitals-KPICZIEF.mjs.map +1 -0
  103. package/package.json +7 -1
  104. package/dist/chunk-3LOFIO77.mjs.map +0 -1
  105. package/dist/chunk-CTKXFLIF.js.map +0 -1
  106. package/dist/chunk-IRNMIFOE.js.map +0 -1
  107. package/dist/chunk-LHMD7CAR.mjs.map +0 -1
  108. package/dist/chunk-TOUIKTXU.mjs.map +0 -1
  109. package/dist/chunk-VFJ3NNCY.js.map +0 -1
  110. package/dist/socket-loader-3FWQWPDQ.js.map +0 -1
  111. package/dist/socket-loader-N5ETWMXW.mjs.map +0 -1
  112. package/dist/web-vitals-PW6MQOKS.js.map +0 -1
  113. package/dist/web-vitals-YSIFBTH7.mjs.map +0 -1
@@ -0,0 +1,32 @@
1
+ import '../chunk-4XPGGLVP.mjs';
2
+
3
+ // src/robots/index.ts
4
+ function createRobots(config) {
5
+ return function robots() {
6
+ const lines = [];
7
+ if (config.managedRobots?.trim()) {
8
+ lines.push(config.managedRobots.trim());
9
+ } else {
10
+ lines.push("User-agent: *");
11
+ lines.push("Allow: /");
12
+ for (const p of config.disallow ?? []) {
13
+ lines.push(`Disallow: ${p}`);
14
+ }
15
+ }
16
+ const base = config.baseUrl.replace(/\/$/, "");
17
+ const sitemapPath = config.sitemapPath ?? "/sitemap.xml";
18
+ const sitemapUrl = `${base}${sitemapPath.startsWith("/") ? "" : "/"}${sitemapPath}`;
19
+ lines.push(`Sitemap: ${sitemapUrl}`);
20
+ return new Response(lines.join("\n"), {
21
+ status: 200,
22
+ headers: {
23
+ "Content-Type": "text/plain; charset=utf-8",
24
+ "Cache-Control": "public, max-age=86400, s-maxage=86400"
25
+ }
26
+ });
27
+ };
28
+ }
29
+
30
+ export { createRobots };
31
+ //# sourceMappingURL=index.mjs.map
32
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/robots/index.ts"],"names":[],"mappings":";;;AA6CO,SAAS,aAAa,MAAA,EAA0D;AACrF,EAAA,OAAO,SAAS,MAAA,GAAmB;AACjC,IAAA,MAAM,QAAkB,EAAC;AAEzB,IAAA,IAAI,MAAA,CAAO,aAAA,EAAe,IAAA,EAAK,EAAG;AAChC,MAAA,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,IAAA,EAAM,CAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,eAAe,CAAA;AAC1B,MAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AACrB,MAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,QAAA,IAAY,EAAC,EAAG;AACrC,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,CAAC,CAAA,CAAE,CAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC7C,IAAA,MAAM,WAAA,GAAc,OAAO,WAAA,IAAe,cAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,CAAA,EAAG,IAAI,CAAA,EAAG,WAAA,CAAY,UAAA,CAAW,GAAG,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,EAAG,WAAW,CAAA,CAAA;AACjF,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,UAAU,CAAA,CAAE,CAAA;AAEnC,IAAA,OAAO,IAAI,QAAA,CAAS,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG;AAAA,MACpC,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,2BAAA;AAAA,QAChB,eAAA,EAAiB;AAAA;AACnB,KACD,CAAA;AAAA,EACH,CAAA;AACF","file":"index.mjs","sourcesContent":["/**\n * @uptrade/site-kit/robots - robots.txt Generator\n *\n * Generates robots.txt with Sitemap directive.\n * Optional: use managed content from Portal if configured.\n *\n * @example\n * ```ts\n * // app/robots.ts (Next.js MetadataRoute)\n * import { createRobots } from '@uptrademedia/site-kit/robots'\n *\n * export default function robots() {\n * return createRobots({\n * baseUrl: 'https://example.com',\n * })()\n * }\n * ```\n *\n * @example\n * ```ts\n * // app/robots.txt/route.ts\n * import { createRobots } from '@uptrademedia/site-kit/robots'\n *\n * export const GET = createRobots({\n * baseUrl: process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com',\n * disallow: ['/admin', '/api'],\n * })\n * ```\n */\n\nexport interface RobotsConfig {\n /** Base URL of the site (e.g. https://example.com) */\n baseUrl: string\n /** Path to sitemap (default: /sitemap.xml) */\n sitemapPath?: string\n /** Pre-built robots content from Portal (overrides default when provided) */\n managedRobots?: string | null\n /** Paths to disallow (e.g. ['/admin', '/api']) */\n disallow?: string[]\n}\n\n/**\n * Create a robots.txt handler that returns a Response.\n * Use as GET handler for app/robots.txt/route.ts or call and return for app/robots.ts.\n */\nexport function createRobots(config: RobotsConfig): () => Response | Promise<Response> {\n return function robots(): Response {\n const lines: string[] = []\n\n if (config.managedRobots?.trim()) {\n lines.push(config.managedRobots.trim())\n } else {\n lines.push('User-agent: *')\n lines.push('Allow: /')\n for (const p of config.disallow ?? []) {\n lines.push(`Disallow: ${p}`)\n }\n }\n\n const base = config.baseUrl.replace(/\\/$/, '')\n const sitemapPath = config.sitemapPath ?? '/sitemap.xml'\n const sitemapUrl = `${base}${sitemapPath.startsWith('/') ? '' : '/'}${sitemapPath}`\n lines.push(`Sitemap: ${sitemapUrl}`)\n\n return new Response(lines.join('\\n'), {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'public, max-age=86400, s-maxage=86400',\n },\n })\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { e as GetSitemapEntriesOptions, s as SitemapEntry, c as GetRedirectOptions, R as RedirectResult, d as GetRobotsOptions, p as RobotsDirective } from './types-BF2v5qX3.js';
1
+ import { m as GetRedirectOptions, R as RedirectResult, q as GetRobotsOptions, p as RobotsDirective, s as GetSitemapEntriesOptions, r as SitemapEntry } from './types-wCtRFR0Y.js';
2
2
 
3
3
  /**
4
4
  * Get redirect for a path if one exists
@@ -1,4 +1,4 @@
1
- import { e as GetSitemapEntriesOptions, s as SitemapEntry, c as GetRedirectOptions, R as RedirectResult, d as GetRobotsOptions, p as RobotsDirective } from './types-BF2v5qX3.mjs';
1
+ import { m as GetRedirectOptions, R as RedirectResult, q as GetRobotsOptions, p as RobotsDirective, s as GetSitemapEntriesOptions, r as SitemapEntry } from './types-wCtRFR0Y.mjs';
2
2
 
3
3
  /**
4
4
  * Get redirect for a path if one exists
@@ -1,4 +1,4 @@
1
- export { scanCodebase, scanForAnalytics, scanForFAQs, scanForForms, scanForImages, scanForManagedFAQPaths, scanForMetadata, scanForSchemas, scanForSitemapFiles, scanForSitemaps, scanForWidgets } from './chunk-3LOFIO77.mjs';
1
+ export { scanCodebase, scanForAnalytics, scanForFAQs, scanForForms, scanForImages, scanForManagedFAQPaths, scanForMetadata, scanForSchemas, scanForSitemapFiles, scanForSitemaps, scanForWidgets } from './chunk-44OMJFCG.mjs';
2
2
  import './chunk-4XPGGLVP.mjs';
3
- //# sourceMappingURL=scanner-VNEXRTZF.mjs.map
4
- //# sourceMappingURL=scanner-VNEXRTZF.mjs.map
3
+ //# sourceMappingURL=scanner-7ZMUM2P5.mjs.map
4
+ //# sourceMappingURL=scanner-7ZMUM2P5.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"scanner-VNEXRTZF.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"scanner-7ZMUM2P5.mjs"}
@@ -1,53 +1,53 @@
1
1
  'use strict';
2
2
 
3
- var chunkVFJ3NNCY_js = require('./chunk-VFJ3NNCY.js');
3
+ var chunkDERI27QC_js = require('./chunk-DERI27QC.js');
4
4
  require('./chunk-ZSMWDLMK.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "scanCodebase", {
9
9
  enumerable: true,
10
- get: function () { return chunkVFJ3NNCY_js.scanCodebase; }
10
+ get: function () { return chunkDERI27QC_js.scanCodebase; }
11
11
  });
12
12
  Object.defineProperty(exports, "scanForAnalytics", {
13
13
  enumerable: true,
14
- get: function () { return chunkVFJ3NNCY_js.scanForAnalytics; }
14
+ get: function () { return chunkDERI27QC_js.scanForAnalytics; }
15
15
  });
16
16
  Object.defineProperty(exports, "scanForFAQs", {
17
17
  enumerable: true,
18
- get: function () { return chunkVFJ3NNCY_js.scanForFAQs; }
18
+ get: function () { return chunkDERI27QC_js.scanForFAQs; }
19
19
  });
20
20
  Object.defineProperty(exports, "scanForForms", {
21
21
  enumerable: true,
22
- get: function () { return chunkVFJ3NNCY_js.scanForForms; }
22
+ get: function () { return chunkDERI27QC_js.scanForForms; }
23
23
  });
24
24
  Object.defineProperty(exports, "scanForImages", {
25
25
  enumerable: true,
26
- get: function () { return chunkVFJ3NNCY_js.scanForImages; }
26
+ get: function () { return chunkDERI27QC_js.scanForImages; }
27
27
  });
28
28
  Object.defineProperty(exports, "scanForManagedFAQPaths", {
29
29
  enumerable: true,
30
- get: function () { return chunkVFJ3NNCY_js.scanForManagedFAQPaths; }
30
+ get: function () { return chunkDERI27QC_js.scanForManagedFAQPaths; }
31
31
  });
32
32
  Object.defineProperty(exports, "scanForMetadata", {
33
33
  enumerable: true,
34
- get: function () { return chunkVFJ3NNCY_js.scanForMetadata; }
34
+ get: function () { return chunkDERI27QC_js.scanForMetadata; }
35
35
  });
36
36
  Object.defineProperty(exports, "scanForSchemas", {
37
37
  enumerable: true,
38
- get: function () { return chunkVFJ3NNCY_js.scanForSchemas; }
38
+ get: function () { return chunkDERI27QC_js.scanForSchemas; }
39
39
  });
40
40
  Object.defineProperty(exports, "scanForSitemapFiles", {
41
41
  enumerable: true,
42
- get: function () { return chunkVFJ3NNCY_js.scanForSitemapFiles; }
42
+ get: function () { return chunkDERI27QC_js.scanForSitemapFiles; }
43
43
  });
44
44
  Object.defineProperty(exports, "scanForSitemaps", {
45
45
  enumerable: true,
46
- get: function () { return chunkVFJ3NNCY_js.scanForSitemaps; }
46
+ get: function () { return chunkDERI27QC_js.scanForSitemaps; }
47
47
  });
48
48
  Object.defineProperty(exports, "scanForWidgets", {
49
49
  enumerable: true,
50
- get: function () { return chunkVFJ3NNCY_js.scanForWidgets; }
50
+ get: function () { return chunkDERI27QC_js.scanForWidgets; }
51
51
  });
52
- //# sourceMappingURL=scanner-CVKYTPUO.js.map
53
- //# sourceMappingURL=scanner-CVKYTPUO.js.map
52
+ //# sourceMappingURL=scanner-OY7UF3WA.js.map
53
+ //# sourceMappingURL=scanner-OY7UF3WA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"scanner-CVKYTPUO.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"scanner-OY7UF3WA.js"}
@@ -1,6 +1,6 @@
1
- import { G as GetABVariantOptions, a as ABTestResult, b as GetManagedMetadataOptions, k as ManagedMetadataResult, m as ManagedSchemaProps, h as ManagedFAQProps, i as ManagedInternalLinksProps, f as ManagedContentProps, M as ManagedContentBlock, o as ManagedScriptsProps } from '../types-BF2v5qX3.mjs';
2
- export { A as ABTest, F as FAQItem, c as GetRedirectOptions, d as GetRobotsOptions, e as GetSitemapEntriesOptions, g as ManagedFAQData, j as ManagedLink, l as ManagedRedirect, n as ManagedScript, R as RedirectResult, p as RobotsDirective, q as SEOPageData, r as SchemaMarkup, s as SitemapEntry, U as UptradeSEOConfig } from '../types-BF2v5qX3.mjs';
3
- export { g as generateSitemap, a as getRedirect, b as getRobotsDirective, i as isIndexable } from '../routing-bTjqOM8S.mjs';
1
+ import { G as GetManagedMetadataOptions, M as ManagedMetadataResult, k as GetABVariantOptions, j as ABTestResult, b as ManagedSchemaProps, d as ManagedFAQProps, f as ManagedInternalLinksProps, h as ManagedContentProps, g as ManagedContentBlock, o as ManagedScriptsProps } from '../types-wCtRFR0Y.mjs';
2
+ export { A as ABTest, F as FAQItem, m as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, c as ManagedFAQData, e as ManagedLink, l as ManagedRedirect, n as ManagedScript, R as RedirectResult, p as RobotsDirective, S as SEOPageData, a as SchemaMarkup, r as SitemapEntry, U as UptradeSEOConfig } from '../types-wCtRFR0Y.mjs';
3
+ export { g as generateSitemap, a as getRedirect, b as getRobotsDirective, i as isIndexable } from '../routing-Bg1nr9N0.mjs';
4
4
  import * as React from 'react';
5
5
  import 'next';
6
6
 
@@ -1,6 +1,6 @@
1
- import { G as GetABVariantOptions, a as ABTestResult, b as GetManagedMetadataOptions, k as ManagedMetadataResult, m as ManagedSchemaProps, h as ManagedFAQProps, i as ManagedInternalLinksProps, f as ManagedContentProps, M as ManagedContentBlock, o as ManagedScriptsProps } from '../types-BF2v5qX3.js';
2
- export { A as ABTest, F as FAQItem, c as GetRedirectOptions, d as GetRobotsOptions, e as GetSitemapEntriesOptions, g as ManagedFAQData, j as ManagedLink, l as ManagedRedirect, n as ManagedScript, R as RedirectResult, p as RobotsDirective, q as SEOPageData, r as SchemaMarkup, s as SitemapEntry, U as UptradeSEOConfig } from '../types-BF2v5qX3.js';
3
- export { g as generateSitemap, a as getRedirect, b as getRobotsDirective, i as isIndexable } from '../routing-D311WhuV.js';
1
+ import { G as GetManagedMetadataOptions, M as ManagedMetadataResult, k as GetABVariantOptions, j as ABTestResult, b as ManagedSchemaProps, d as ManagedFAQProps, f as ManagedInternalLinksProps, h as ManagedContentProps, g as ManagedContentBlock, o as ManagedScriptsProps } from '../types-wCtRFR0Y.js';
2
+ export { A as ABTest, F as FAQItem, m as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, c as ManagedFAQData, e as ManagedLink, l as ManagedRedirect, n as ManagedScript, R as RedirectResult, p as RobotsDirective, S as SEOPageData, a as SchemaMarkup, r as SitemapEntry, U as UptradeSEOConfig } from '../types-wCtRFR0Y.js';
3
+ export { g as generateSitemap, a as getRedirect, b as getRobotsDirective, i as isIndexable } from '../routing-BI69sU8F.js';
4
4
  import * as React from 'react';
5
5
  import 'next';
6
6
 
@@ -1,5 +1,5 @@
1
- export { g as generateSitemap, r as registerLocalSitemap } from '../routing-bTjqOM8S.mjs';
2
- export { A as ABTest, a as ABTestResult, F as FAQItem, G as GetABVariantOptions, b as GetManagedMetadataOptions, c as GetRedirectOptions, d as GetRobotsOptions, e as GetSitemapEntriesOptions, M as ManagedContentBlock, f as ManagedContentProps, g as ManagedFAQData, h as ManagedFAQProps, i as ManagedInternalLinksProps, j as ManagedLink, k as ManagedMetadataResult, l as ManagedRedirect, m as ManagedSchemaProps, n as ManagedScript, o as ManagedScriptsProps, R as RedirectResult, p as RobotsDirective, S as SEOEntity, q as SEOPageData, r as SchemaMarkup, s as SitemapEntry, U as UptradeSEOConfig } from '../types-BF2v5qX3.mjs';
1
+ export { g as generateSitemap, r as registerLocalSitemap } from '../routing-Bg1nr9N0.mjs';
2
+ export { A as ABTest, j as ABTestResult, F as FAQItem, k as GetABVariantOptions, G as GetManagedMetadataOptions, m as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, g as ManagedContentBlock, h as ManagedContentProps, c as ManagedFAQData, d as ManagedFAQProps, f as ManagedInternalLinksProps, e as ManagedLink, M as ManagedMetadataResult, l as ManagedRedirect, b as ManagedSchemaProps, n as ManagedScript, o as ManagedScriptsProps, R as RedirectResult, p as RobotsDirective, i as SEOEntity, S as SEOPageData, a as SchemaMarkup, r as SitemapEntry, U as UptradeSEOConfig } from '../types-wCtRFR0Y.mjs';
3
3
  import 'next';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- export { g as generateSitemap, r as registerLocalSitemap } from '../routing-D311WhuV.js';
2
- export { A as ABTest, a as ABTestResult, F as FAQItem, G as GetABVariantOptions, b as GetManagedMetadataOptions, c as GetRedirectOptions, d as GetRobotsOptions, e as GetSitemapEntriesOptions, M as ManagedContentBlock, f as ManagedContentProps, g as ManagedFAQData, h as ManagedFAQProps, i as ManagedInternalLinksProps, j as ManagedLink, k as ManagedMetadataResult, l as ManagedRedirect, m as ManagedSchemaProps, n as ManagedScript, o as ManagedScriptsProps, R as RedirectResult, p as RobotsDirective, S as SEOEntity, q as SEOPageData, r as SchemaMarkup, s as SitemapEntry, U as UptradeSEOConfig } from '../types-BF2v5qX3.js';
1
+ export { g as generateSitemap, r as registerLocalSitemap } from '../routing-BI69sU8F.js';
2
+ export { A as ABTest, j as ABTestResult, F as FAQItem, k as GetABVariantOptions, G as GetManagedMetadataOptions, m as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, g as ManagedContentBlock, h as ManagedContentProps, c as ManagedFAQData, d as ManagedFAQProps, f as ManagedInternalLinksProps, e as ManagedLink, M as ManagedMetadataResult, l as ManagedRedirect, b as ManagedSchemaProps, n as ManagedScript, o as ManagedScriptsProps, R as RedirectResult, p as RobotsDirective, i as SEOEntity, S as SEOPageData, a as SchemaMarkup, r as SitemapEntry, U as UptradeSEOConfig } from '../types-wCtRFR0Y.js';
3
3
  import 'next';
4
4
 
5
5
  /**
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk5TTUNB63_js = require('../chunk-5TTUNB63.js');
4
- var chunkHEUULOSC_js = require('../chunk-HEUULOSC.js');
4
+ var chunk2MNLOYDD_js = require('../chunk-2MNLOYDD.js');
5
5
  var chunkGHSZWROI_js = require('../chunk-GHSZWROI.js');
6
6
  require('../chunk-ZSMWDLMK.js');
7
7
 
@@ -21,7 +21,7 @@ Object.defineProperty(exports, "getSnippetsByModule", {
21
21
  });
22
22
  Object.defineProperty(exports, "handleRequest", {
23
23
  enumerable: true,
24
- get: function () { return chunkHEUULOSC_js.handleRequest; }
24
+ get: function () { return chunk2MNLOYDD_js.handleRequest; }
25
25
  });
26
26
  Object.defineProperty(exports, "SetupWizard", {
27
27
  enumerable: true,
@@ -1,5 +1,5 @@
1
1
  export { IntegrationCodeView, generateIntegrationCode, getSnippetsByModule } from '../chunk-TEYPRKYU.mjs';
2
- export { handleRequest } from '../chunk-YT5SBY5W.mjs';
2
+ export { handleRequest } from '../chunk-MLJXNFUO.mjs';
3
3
  export { SetupWizard, SetupWizard as UptradeSetup } from '../chunk-ZUYWXUHQ.mjs';
4
4
  import '../chunk-4XPGGLVP.mjs';
5
5
  //# sourceMappingURL=index.mjs.map
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunkHEUULOSC_js = require('../chunk-HEUULOSC.js');
3
+ var chunk2MNLOYDD_js = require('../chunk-2MNLOYDD.js');
4
4
  require('../chunk-ZSMWDLMK.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "handleRequest", {
9
9
  enumerable: true,
10
- get: function () { return chunkHEUULOSC_js.handleRequest; }
10
+ get: function () { return chunk2MNLOYDD_js.handleRequest; }
11
11
  });
12
12
  //# sourceMappingURL=server.js.map
13
13
  //# sourceMappingURL=server.js.map
@@ -1,4 +1,4 @@
1
- export { handleRequest } from '../chunk-YT5SBY5W.mjs';
1
+ export { handleRequest } from '../chunk-MLJXNFUO.mjs';
2
2
  import '../chunk-4XPGGLVP.mjs';
3
3
  //# sourceMappingURL=server.mjs.map
4
4
  //# sourceMappingURL=server.mjs.map
@@ -1,3 +1,5 @@
1
+ import { L as LLMsDataResponse } from '../types-D8i7Alvv.mjs';
2
+
1
3
  /**
2
4
  * @uptrade/site-kit - Sitemap Generator
3
5
  *
@@ -51,10 +53,12 @@ interface SitemapConfig {
51
53
  disableSync?: boolean;
52
54
  /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */
53
55
  awaitMetaOptimization?: boolean;
54
- /** When true, write AI-optimized llms.txt to public/llms.txt after sitemap sync */
56
+ /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */
55
57
  optimizedLLMsTxt?: boolean;
56
58
  /** When true with optimizedLLMsTxt, also write public/llms-full.txt */
57
59
  optimizedLLMsFullTxt?: boolean;
60
+ /** When Portal returns empty services, use this to supply local site data for llms.txt */
61
+ getLocalData?: () => Promise<LLMsDataResponse | null>;
58
62
  }
59
63
  interface SyncSitemapOptions {
60
64
  /** Trigger Signal AI meta optimization after sync */
@@ -1,3 +1,5 @@
1
+ import { L as LLMsDataResponse } from '../types-D8i7Alvv.js';
2
+
1
3
  /**
2
4
  * @uptrade/site-kit - Sitemap Generator
3
5
  *
@@ -51,10 +53,12 @@ interface SitemapConfig {
51
53
  disableSync?: boolean;
52
54
  /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */
53
55
  awaitMetaOptimization?: boolean;
54
- /** When true, write AI-optimized llms.txt to public/llms.txt after sitemap sync */
56
+ /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */
55
57
  optimizedLLMsTxt?: boolean;
56
58
  /** When true with optimizedLLMsTxt, also write public/llms-full.txt */
57
59
  optimizedLLMsFullTxt?: boolean;
60
+ /** When Portal returns empty services, use this to supply local site data for llms.txt */
61
+ getLocalData?: () => Promise<LLMsDataResponse | null>;
58
62
  }
59
63
  interface SyncSitemapOptions {
60
64
  /** Trigger Signal AI meta optimization after sync */
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkIRNMIFOE_js = require('../chunk-IRNMIFOE.js');
3
+ var chunkICHCPLRB_js = require('../chunk-ICHCPLRB.js');
4
4
  require('../chunk-ZSMWDLMK.js');
5
5
  var fs = require('fs');
6
6
  var path = require('path');
@@ -201,13 +201,14 @@ function createSitemap(config) {
201
201
  if (result.success) {
202
202
  console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`);
203
203
  }
204
- if (config.optimizedLLMsTxt) {
204
+ if (config.optimizedLLMsTxt !== false) {
205
205
  try {
206
- const writeResult = await chunkIRNMIFOE_js.writeLLMsTxtToPublic({
206
+ const writeResult = await chunkICHCPLRB_js.writeLLMsTxtToPublic({
207
207
  apiUrl,
208
208
  apiKey,
209
209
  full: config.optimizedLLMsFullTxt ?? false,
210
- fallbackToLocal: true
210
+ fallbackToLocal: true,
211
+ getLocalData: config.getLocalData
211
212
  });
212
213
  if (writeResult.success) {
213
214
  console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sitemap/index.ts"],"names":["join","existsSync","readdirSync","statSync","writeLLMsTxtToPublic"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @uptrade/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (required) */\n baseUrl: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_URL or https://api.uptrademedia.com) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true, write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'uptrade-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Recursively discover pages from the app directory\n */\nfunction discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = []\n): string[] {\n const fullPath = join(appDir, currentPath)\n \n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n \n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n \n if (hasPage) {\n // Convert directory path to URL path\n let urlPath = '/' + currentPath\n \n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n \n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n \n pages.push(urlPath)\n }\n \n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n \n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n \n // Skip dynamic route segments for now (would need runtime data)\n if (entry.startsWith('[') && entry.endsWith(']')) {\n continue\n }\n \n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n \n discoverPages(appDir, join(currentPath, entry), pages)\n }\n }\n \n return pages\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { baseUrl, exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Normalize base URL\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/uptrade-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = discoverPages(appDir)\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Filter out excluded pages\n pages = pages.filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided\n if (config.additionalPaths) {\n try {\n const additional = await config.additionalPaths()\n for (const item of additional) {\n if (!isExcluded(item.path, allExclusions)) {\n entries.push({\n url: `${normalizedBaseUrl}${item.path}`,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n \n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n // Server-side operations use UPTRADE_API_KEY, not NEXT_PUBLIC_\n const apiKey = config.apiKey || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n }\n\n // Write AI-optimized llms.txt after sync (when enabled)\n if (config.optimizedLLMsTxt) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/sitemap/index.ts"],"names":["join","existsSync","readdirSync","statSync","writeLLMsTxtToPublic"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @uptrade/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (required) */\n baseUrl: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_URL or https://api.uptrademedia.com) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'uptrade-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Recursively discover pages from the app directory\n */\nfunction discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = []\n): string[] {\n const fullPath = join(appDir, currentPath)\n \n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n \n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n \n if (hasPage) {\n // Convert directory path to URL path\n let urlPath = '/' + currentPath\n \n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n \n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n \n pages.push(urlPath)\n }\n \n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n \n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n \n // Skip dynamic route segments for now (would need runtime data)\n if (entry.startsWith('[') && entry.endsWith(']')) {\n continue\n }\n \n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n \n discoverPages(appDir, join(currentPath, entry), pages)\n }\n }\n \n return pages\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { baseUrl, exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Normalize base URL\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/uptrade-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = discoverPages(appDir)\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Filter out excluded pages\n pages = pages.filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided\n if (config.additionalPaths) {\n try {\n const additional = await config.additionalPaths()\n for (const item of additional) {\n if (!isExcluded(item.path, allExclusions)) {\n entries.push({\n url: `${normalizedBaseUrl}${item.path}`,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n \n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n // Server-side operations use UPTRADE_API_KEY, not NEXT_PUBLIC_\n const apiKey = config.apiKey || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { writeLLMsTxtToPublic } from '../chunk-LHMD7CAR.mjs';
1
+ import { writeLLMsTxtToPublic } from '../chunk-2STSAGNT.mjs';
2
2
  import '../chunk-4XPGGLVP.mjs';
3
3
  import { existsSync, readdirSync, statSync } from 'fs';
4
4
  import { join } from 'path';
@@ -199,13 +199,14 @@ function createSitemap(config) {
199
199
  if (result.success) {
200
200
  console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`);
201
201
  }
202
- if (config.optimizedLLMsTxt) {
202
+ if (config.optimizedLLMsTxt !== false) {
203
203
  try {
204
204
  const writeResult = await writeLLMsTxtToPublic({
205
205
  apiUrl,
206
206
  apiKey,
207
207
  full: config.optimizedLLMsFullTxt ?? false,
208
- fallbackToLocal: true
208
+ fallbackToLocal: true,
209
+ getLocalData: config.getLocalData
209
210
  });
210
211
  if (writeResult.success) {
211
212
  console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @uptrade/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (required) */\n baseUrl: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_URL or https://api.uptrademedia.com) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true, write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'uptrade-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Recursively discover pages from the app directory\n */\nfunction discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = []\n): string[] {\n const fullPath = join(appDir, currentPath)\n \n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n \n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n \n if (hasPage) {\n // Convert directory path to URL path\n let urlPath = '/' + currentPath\n \n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n \n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n \n pages.push(urlPath)\n }\n \n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n \n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n \n // Skip dynamic route segments for now (would need runtime data)\n if (entry.startsWith('[') && entry.endsWith(']')) {\n continue\n }\n \n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n \n discoverPages(appDir, join(currentPath, entry), pages)\n }\n }\n \n return pages\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { baseUrl, exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Normalize base URL\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/uptrade-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = discoverPages(appDir)\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Filter out excluded pages\n pages = pages.filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided\n if (config.additionalPaths) {\n try {\n const additional = await config.additionalPaths()\n for (const item of additional) {\n if (!isExcluded(item.path, allExclusions)) {\n entries.push({\n url: `${normalizedBaseUrl}${item.path}`,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n \n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n // Server-side operations use UPTRADE_API_KEY, not NEXT_PUBLIC_\n const apiKey = config.apiKey || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n }\n\n // Write AI-optimized llms.txt after sync (when enabled)\n if (config.optimizedLLMsTxt) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @uptrade/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (required) */\n baseUrl: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_URL or https://api.uptrademedia.com) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to NEXT_PUBLIC_UPTRADE_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'uptrade-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Recursively discover pages from the app directory\n */\nfunction discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = []\n): string[] {\n const fullPath = join(appDir, currentPath)\n \n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n \n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n \n if (hasPage) {\n // Convert directory path to URL path\n let urlPath = '/' + currentPath\n \n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n \n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n \n pages.push(urlPath)\n }\n \n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n \n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n \n // Skip dynamic route segments for now (would need runtime data)\n if (entry.startsWith('[') && entry.endsWith(']')) {\n continue\n }\n \n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n \n discoverPages(appDir, join(currentPath, entry), pages)\n }\n }\n \n return pages\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@uptrade/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { baseUrl, exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Normalize base URL\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/uptrade-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = discoverPages(appDir)\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Filter out excluded pages\n pages = pages.filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided\n if (config.additionalPaths) {\n try {\n const additional = await config.additionalPaths()\n for (const item of additional) {\n if (!isExcluded(item.path, allExclusions)) {\n entries.push({\n url: `${normalizedBaseUrl}${item.path}`,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n \n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n // Server-side operations use UPTRADE_API_KEY, not NEXT_PUBLIC_\n const apiKey = config.apiKey || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
@@ -12,5 +12,5 @@ async function createSocket(url, opts) {
12
12
  }
13
13
 
14
14
  exports.createSocket = createSocket;
15
- //# sourceMappingURL=socket-loader-3FWQWPDQ.js.map
16
- //# sourceMappingURL=socket-loader-3FWQWPDQ.js.map
15
+ //# sourceMappingURL=socket-loader-J26QHHOB.js.map
16
+ //# sourceMappingURL=socket-loader-J26QHHOB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engage/socket-loader.ts"],"names":[],"mappings":";;;;;AAOA,eAAsB,YAAA,CACpB,KACA,IAAA,EACiB;AACjB,EAAA,MAAM,EAAE,EAAA,EAAG,GAAI,MAAM;AAAA;AAAA,IAA2C;AAAA,GAAkB;AAClF,EAAA,OAAO,EAAA,CAAG,KAAK,IAAI,CAAA;AACrB","file":"socket-loader-J26QHHOB.js","sourcesContent":["import type { Socket } from 'socket.io-client'\n\n/**\n * Lazy socket.io loader — kept in a separate file so bundlers\n * (Turbopack, webpack) never pull socket.io-client into the main\n * engage chunk. Only loaded when the user actually opens the chat.\n */\nexport async function createSocket(\n url: string,\n opts: Record<string, unknown>,\n): Promise<Socket> {\n const { io } = await import(/* webpackChunkName: \"socket-io\" */ 'socket.io-client')\n return io(url, opts)\n}\n"]}
@@ -10,5 +10,5 @@ async function createSocket(url, opts) {
10
10
  }
11
11
 
12
12
  export { createSocket };
13
- //# sourceMappingURL=socket-loader-N5ETWMXW.mjs.map
14
- //# sourceMappingURL=socket-loader-N5ETWMXW.mjs.map
13
+ //# sourceMappingURL=socket-loader-R7S2YJ2J.mjs.map
14
+ //# sourceMappingURL=socket-loader-R7S2YJ2J.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engage/socket-loader.ts"],"names":[],"mappings":";;;AAOA,eAAsB,YAAA,CACpB,KACA,IAAA,EACiB;AACjB,EAAA,MAAM,EAAE,EAAA,EAAG,GAAI,MAAM;AAAA;AAAA,IAA2C;AAAA,GAAkB;AAClF,EAAA,OAAO,EAAA,CAAG,KAAK,IAAI,CAAA;AACrB","file":"socket-loader-R7S2YJ2J.mjs","sourcesContent":["import type { Socket } from 'socket.io-client'\n\n/**\n * Lazy socket.io loader — kept in a separate file so bundlers\n * (Turbopack, webpack) never pull socket.io-client into the main\n * engage chunk. Only loaded when the user actually opens the chat.\n */\nexport async function createSocket(\n url: string,\n opts: Record<string, unknown>,\n): Promise<Socket> {\n const { io } = await import(/* webpackChunkName: \"socket-io\" */ 'socket.io-client')\n return io(url, opts)\n}\n"]}
@@ -247,4 +247,4 @@ interface EngageAnalytics {
247
247
  created_at: string;
248
248
  }
249
249
 
250
- export { type ActionConfig as A, type ChatConfig as C, type DesignDocument as D, type EngageAnalytics as E, type TargetingRules as T, type WidgetConfig as W, type ChatAvailability as a, type ChatConversation as b, type ChatMessage as c, type DesignNode as d, DesignRenderer as e, type EngageConfig as f, type EngageContext as g, type EngageElement as h, type TriggerConfig as i, type WidgetType as j };
250
+ export { type ActionConfig as A, type ChatConfig as C, DesignRenderer as D, type EngageContext as E, type TargetingRules as T, type WidgetType as W, type DesignDocument as a, type DesignNode as b, type EngageElement as c, type WidgetConfig as d, type TriggerConfig as e, type ChatMessage as f, type ChatConversation as g, type ChatAvailability as h, type EngageConfig as i, type EngageAnalytics as j };
@@ -247,4 +247,4 @@ interface EngageAnalytics {
247
247
  created_at: string;
248
248
  }
249
249
 
250
- export { type ActionConfig as A, type ChatConfig as C, type DesignDocument as D, type EngageAnalytics as E, type TargetingRules as T, type WidgetConfig as W, type ChatAvailability as a, type ChatConversation as b, type ChatMessage as c, type DesignNode as d, DesignRenderer as e, type EngageConfig as f, type EngageContext as g, type EngageElement as h, type TriggerConfig as i, type WidgetType as j };
250
+ export { type ActionConfig as A, type ChatConfig as C, DesignRenderer as D, type EngageContext as E, type TargetingRules as T, type WidgetType as W, type DesignDocument as a, type DesignNode as b, type EngageElement as c, type WidgetConfig as d, type TriggerConfig as e, type ChatMessage as f, type ChatConversation as g, type ChatAvailability as h, type EngageConfig as i, type EngageAnalytics as j };
@@ -309,4 +309,4 @@ interface FetchEventsOptions {
309
309
  category?: string;
310
310
  }
311
311
 
312
- export type { AdditionalField as A, CommerceOffering as C, EventEmbedProps as E, FetchEventsOptions as F, OfferingType as O, PriceType as P, RegistrationFormProps as R, UpcomingEventsProps as U, CommerceVariant as a, CheckoutResult as b, CommerceSchedule as c, AdditionalFieldOption as d, Cart as e, CartItem as f, CheckoutCustomer as g, CheckoutFormProps as h, CommerceApiConfig as i, CommerceCategory as j, EventTileProps as k, FetchOfferingsOptions as l, OfferingCardProps as m, OfferingDetailProps as n, OfferingListProps as o, OfferingStatus as p, ProductEmbedProps as q };
312
+ export type { AdditionalFieldOption as A, CommerceOffering as C, EventTileProps as E, FetchOfferingsOptions as F, OfferingType as O, PriceType as P, RegistrationFormProps as R, UpcomingEventsProps as U, CommerceVariant as a, CheckoutResult as b, CommerceSchedule as c, OfferingStatus as d, CommerceCategory as e, CartItem as f, Cart as g, CheckoutCustomer as h, OfferingCardProps as i, OfferingListProps as j, OfferingDetailProps as k, ProductEmbedProps as l, EventEmbedProps as m, CheckoutFormProps as n, AdditionalField as o, CommerceApiConfig as p, FetchEventsOptions as q };