@uptrademedia/site-kit 1.0.9 → 1.0.10

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 (55) hide show
  1. package/dist/api-CWtoFJCO.d.mts +137 -0
  2. package/dist/api-CWtoFJCO.d.ts +137 -0
  3. package/dist/{api-QUIPJJCX.js → api-UBHLAPUG.js} +20 -20
  4. package/dist/api-UBHLAPUG.js.map +1 -0
  5. package/dist/{api-V3BA5PMX.mjs → api-XNF6Q5HO.mjs} +3 -3
  6. package/dist/api-XNF6Q5HO.mjs.map +1 -0
  7. package/dist/{chunk-QQB4FO4Q.js → chunk-AWAJEIZS.js} +11 -8
  8. package/dist/chunk-AWAJEIZS.js.map +1 -0
  9. package/dist/{chunk-MB3WR5KJ.mjs → chunk-CDJL2YGL.mjs} +61 -443
  10. package/dist/chunk-CDJL2YGL.mjs.map +1 -0
  11. package/dist/{chunk-TDK7DLCH.js → chunk-FLAA4ZJO.js} +59 -448
  12. package/dist/chunk-FLAA4ZJO.js.map +1 -0
  13. package/dist/{chunk-JGQPAXTL.mjs → chunk-H5AGHERY.mjs} +8 -5
  14. package/dist/chunk-H5AGHERY.mjs.map +1 -0
  15. package/dist/{chunk-VDI7KYME.js → chunk-IYVJGUYX.js} +8 -4
  16. package/dist/chunk-IYVJGUYX.js.map +1 -0
  17. package/dist/{chunk-FQVGK746.mjs → chunk-SKHOW2CI.mjs} +8 -4
  18. package/dist/chunk-SKHOW2CI.mjs.map +1 -0
  19. package/dist/cli/index.js +32 -25
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/index.mjs +32 -25
  22. package/dist/cli/index.mjs.map +1 -1
  23. package/dist/images/index.d.mts +49 -126
  24. package/dist/images/index.d.ts +49 -126
  25. package/dist/images/index.js +12 -12
  26. package/dist/images/index.mjs +1 -5
  27. package/dist/index.d.mts +2 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +510 -106
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +440 -13
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/{routing-CIOFpFCB.d.mts → routing-BT0RrBLk.d.mts} +14 -1
  34. package/dist/{routing-CF91y6NO.d.ts → routing-wmNSxSvP.d.ts} +14 -1
  35. package/dist/seo/index.d.mts +37 -4
  36. package/dist/seo/index.d.ts +37 -4
  37. package/dist/seo/index.js +48 -18
  38. package/dist/seo/index.js.map +1 -1
  39. package/dist/seo/index.mjs +34 -5
  40. package/dist/seo/index.mjs.map +1 -1
  41. package/dist/seo/server.d.mts +15 -4
  42. package/dist/seo/server.d.ts +15 -4
  43. package/dist/seo/server.js +16 -16
  44. package/dist/seo/server.mjs +2 -2
  45. package/dist/{types-j8X4vUhB.d.mts → types-wf4dwNMO.d.mts} +5 -0
  46. package/dist/{types-j8X4vUhB.d.ts → types-wf4dwNMO.d.ts} +5 -0
  47. package/package.json +1 -1
  48. package/dist/api-QUIPJJCX.js.map +0 -1
  49. package/dist/api-V3BA5PMX.mjs.map +0 -1
  50. package/dist/chunk-FQVGK746.mjs.map +0 -1
  51. package/dist/chunk-JGQPAXTL.mjs.map +0 -1
  52. package/dist/chunk-MB3WR5KJ.mjs.map +0 -1
  53. package/dist/chunk-QQB4FO4Q.js.map +0 -1
  54. package/dist/chunk-TDK7DLCH.js.map +0 -1
  55. package/dist/chunk-VDI7KYME.js.map +0 -1
@@ -0,0 +1,137 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ interface ManagedImageData {
5
+ id: string;
6
+ slot_id: string;
7
+ page_path: string | null;
8
+ file_id: string | null;
9
+ external_url: string | null;
10
+ alt_text: string | null;
11
+ title: string | null;
12
+ caption: string | null;
13
+ focal_point_x: number;
14
+ focal_point_y: number;
15
+ aspect_ratio: string | null;
16
+ public_url?: string;
17
+ is_placeholder: boolean;
18
+ }
19
+ interface ImageFile {
20
+ id: string;
21
+ filename: string;
22
+ storage_path: string;
23
+ mime_type: string;
24
+ file_size: number;
25
+ folder_path: string | null;
26
+ public_url?: string;
27
+ }
28
+ interface ManagedImageProps {
29
+ /** API key for Portal API */
30
+ apiKey?: string;
31
+ /** API URL (defaults to https://api.uptrademedia.com) */
32
+ apiUrl?: string;
33
+ /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */
34
+ slotId: string;
35
+ /** Page path for page-specific slots (defaults to current path) */
36
+ pagePath?: string;
37
+ /** Fallback alt text if not set in Portal */
38
+ alt?: string;
39
+ /** CSS class names */
40
+ className?: string;
41
+ /** Image width */
42
+ width?: number | string;
43
+ /** Image height */
44
+ height?: number | string;
45
+ /** CSS object-fit property */
46
+ objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
47
+ /** Fallback image URL when no image assigned */
48
+ fallback?: string;
49
+ /** Custom placeholder component */
50
+ placeholder?: React__default.ReactNode;
51
+ /** Called when image loads */
52
+ onLoad?: () => void;
53
+ /** Called on error */
54
+ onError?: (error: Error) => void;
55
+ /** Priority loading (Next.js Image optimization) */
56
+ priority?: boolean;
57
+ /** Additional styles */
58
+ style?: React__default.CSSProperties;
59
+ /** Enable dev picker even outside dev mode */
60
+ forceDevMode?: boolean;
61
+ }
62
+ declare function ManagedImage({ apiKey, apiUrl, slotId, pagePath, alt, className, width, height, objectFit, fallback, placeholder, onLoad, onError, priority, style, forceDevMode, }: ManagedImageProps): react_jsx_runtime.JSX.Element;
63
+
64
+ /**
65
+ * Images API functions
66
+ *
67
+ * All functions use Portal API with API key authentication.
68
+ * Never makes direct Supabase calls.
69
+ */
70
+
71
+ interface ImageApiConfig {
72
+ apiUrl: string;
73
+ apiKey: string;
74
+ }
75
+ /**
76
+ * Fetch a managed image for a specific slot
77
+ */
78
+ declare function fetchManagedImage(config: ImageApiConfig, slotId: string, pagePath?: string): Promise<{
79
+ image: ManagedImageData | null;
80
+ is_placeholder: boolean;
81
+ }>;
82
+ /**
83
+ * Fetch all managed images for the project
84
+ */
85
+ declare function fetchManagedImages(config: ImageApiConfig, options?: {
86
+ pagePath?: string;
87
+ category?: string;
88
+ includePlaceholders?: boolean;
89
+ }): Promise<{
90
+ images: ManagedImageData[];
91
+ }>;
92
+ /**
93
+ * List available image files in the project
94
+ */
95
+ declare function listImageFiles(config: ImageApiConfig, options?: {
96
+ folder?: string;
97
+ search?: string;
98
+ }): Promise<{
99
+ files: ImageFile[];
100
+ folders: string[];
101
+ }>;
102
+ /**
103
+ * Upload a new image
104
+ */
105
+ declare function uploadImage(config: ImageApiConfig, file: File, options?: {
106
+ slotId?: string;
107
+ pagePath?: string;
108
+ folder?: string;
109
+ altText?: string;
110
+ }): Promise<{
111
+ file: ImageFile;
112
+ image?: ManagedImageData;
113
+ }>;
114
+ /**
115
+ * Assign an existing file to an image slot
116
+ */
117
+ declare function assignImageToSlot(config: ImageApiConfig, slotId: string, options: {
118
+ fileId?: string;
119
+ externalUrl?: string;
120
+ pagePath?: string;
121
+ altText?: string;
122
+ title?: string;
123
+ caption?: string;
124
+ focalPointX?: number;
125
+ focalPointY?: number;
126
+ aspectRatio?: string;
127
+ }): Promise<{
128
+ image: ManagedImageData;
129
+ }>;
130
+ /**
131
+ * Clear an image from a slot (keeps the file)
132
+ */
133
+ declare function clearImageSlot(config: ImageApiConfig, slotId: string, pagePath?: string): Promise<{
134
+ success: boolean;
135
+ }>;
136
+
137
+ export { type ImageFile as I, ManagedImage as M, type ManagedImageProps as a, type ManagedImageData as b, fetchManagedImages as c, assignImageToSlot as d, clearImageSlot as e, fetchManagedImage as f, type ImageApiConfig as g, listImageFiles as l, uploadImage as u };
@@ -0,0 +1,137 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ interface ManagedImageData {
5
+ id: string;
6
+ slot_id: string;
7
+ page_path: string | null;
8
+ file_id: string | null;
9
+ external_url: string | null;
10
+ alt_text: string | null;
11
+ title: string | null;
12
+ caption: string | null;
13
+ focal_point_x: number;
14
+ focal_point_y: number;
15
+ aspect_ratio: string | null;
16
+ public_url?: string;
17
+ is_placeholder: boolean;
18
+ }
19
+ interface ImageFile {
20
+ id: string;
21
+ filename: string;
22
+ storage_path: string;
23
+ mime_type: string;
24
+ file_size: number;
25
+ folder_path: string | null;
26
+ public_url?: string;
27
+ }
28
+ interface ManagedImageProps {
29
+ /** API key for Portal API */
30
+ apiKey?: string;
31
+ /** API URL (defaults to https://api.uptrademedia.com) */
32
+ apiUrl?: string;
33
+ /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */
34
+ slotId: string;
35
+ /** Page path for page-specific slots (defaults to current path) */
36
+ pagePath?: string;
37
+ /** Fallback alt text if not set in Portal */
38
+ alt?: string;
39
+ /** CSS class names */
40
+ className?: string;
41
+ /** Image width */
42
+ width?: number | string;
43
+ /** Image height */
44
+ height?: number | string;
45
+ /** CSS object-fit property */
46
+ objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
47
+ /** Fallback image URL when no image assigned */
48
+ fallback?: string;
49
+ /** Custom placeholder component */
50
+ placeholder?: React__default.ReactNode;
51
+ /** Called when image loads */
52
+ onLoad?: () => void;
53
+ /** Called on error */
54
+ onError?: (error: Error) => void;
55
+ /** Priority loading (Next.js Image optimization) */
56
+ priority?: boolean;
57
+ /** Additional styles */
58
+ style?: React__default.CSSProperties;
59
+ /** Enable dev picker even outside dev mode */
60
+ forceDevMode?: boolean;
61
+ }
62
+ declare function ManagedImage({ apiKey, apiUrl, slotId, pagePath, alt, className, width, height, objectFit, fallback, placeholder, onLoad, onError, priority, style, forceDevMode, }: ManagedImageProps): react_jsx_runtime.JSX.Element;
63
+
64
+ /**
65
+ * Images API functions
66
+ *
67
+ * All functions use Portal API with API key authentication.
68
+ * Never makes direct Supabase calls.
69
+ */
70
+
71
+ interface ImageApiConfig {
72
+ apiUrl: string;
73
+ apiKey: string;
74
+ }
75
+ /**
76
+ * Fetch a managed image for a specific slot
77
+ */
78
+ declare function fetchManagedImage(config: ImageApiConfig, slotId: string, pagePath?: string): Promise<{
79
+ image: ManagedImageData | null;
80
+ is_placeholder: boolean;
81
+ }>;
82
+ /**
83
+ * Fetch all managed images for the project
84
+ */
85
+ declare function fetchManagedImages(config: ImageApiConfig, options?: {
86
+ pagePath?: string;
87
+ category?: string;
88
+ includePlaceholders?: boolean;
89
+ }): Promise<{
90
+ images: ManagedImageData[];
91
+ }>;
92
+ /**
93
+ * List available image files in the project
94
+ */
95
+ declare function listImageFiles(config: ImageApiConfig, options?: {
96
+ folder?: string;
97
+ search?: string;
98
+ }): Promise<{
99
+ files: ImageFile[];
100
+ folders: string[];
101
+ }>;
102
+ /**
103
+ * Upload a new image
104
+ */
105
+ declare function uploadImage(config: ImageApiConfig, file: File, options?: {
106
+ slotId?: string;
107
+ pagePath?: string;
108
+ folder?: string;
109
+ altText?: string;
110
+ }): Promise<{
111
+ file: ImageFile;
112
+ image?: ManagedImageData;
113
+ }>;
114
+ /**
115
+ * Assign an existing file to an image slot
116
+ */
117
+ declare function assignImageToSlot(config: ImageApiConfig, slotId: string, options: {
118
+ fileId?: string;
119
+ externalUrl?: string;
120
+ pagePath?: string;
121
+ altText?: string;
122
+ title?: string;
123
+ caption?: string;
124
+ focalPointX?: number;
125
+ focalPointY?: number;
126
+ aspectRatio?: string;
127
+ }): Promise<{
128
+ image: ManagedImageData;
129
+ }>;
130
+ /**
131
+ * Clear an image from a slot (keeps the file)
132
+ */
133
+ declare function clearImageSlot(config: ImageApiConfig, slotId: string, pagePath?: string): Promise<{
134
+ success: boolean;
135
+ }>;
136
+
137
+ export { type ImageFile as I, ManagedImage as M, type ManagedImageProps as a, type ManagedImageData as b, fetchManagedImages as c, assignImageToSlot as d, clearImageSlot as e, fetchManagedImage as f, type ImageApiConfig as g, listImageFiles as l, uploadImage as u };
@@ -1,77 +1,77 @@
1
1
  'use strict';
2
2
 
3
- var chunkVDI7KYME_js = require('./chunk-VDI7KYME.js');
3
+ var chunkIYVJGUYX_js = require('./chunk-IYVJGUYX.js');
4
4
  require('./chunk-ZSMWDLMK.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "getABTest", {
9
9
  enumerable: true,
10
- get: function () { return chunkVDI7KYME_js.getABTest; }
10
+ get: function () { return chunkIYVJGUYX_js.getABTest; }
11
11
  });
12
12
  Object.defineProperty(exports, "getContentBlock", {
13
13
  enumerable: true,
14
- get: function () { return chunkVDI7KYME_js.getContentBlock; }
14
+ get: function () { return chunkIYVJGUYX_js.getContentBlock; }
15
15
  });
16
16
  Object.defineProperty(exports, "getEntities", {
17
17
  enumerable: true,
18
- get: function () { return chunkVDI7KYME_js.getEntities; }
18
+ get: function () { return chunkIYVJGUYX_js.getEntities; }
19
19
  });
20
20
  Object.defineProperty(exports, "getEntityEnhancedSchema", {
21
21
  enumerable: true,
22
- get: function () { return chunkVDI7KYME_js.getEntityEnhancedSchema; }
22
+ get: function () { return chunkIYVJGUYX_js.getEntityEnhancedSchema; }
23
23
  });
24
24
  Object.defineProperty(exports, "getFAQData", {
25
25
  enumerable: true,
26
- get: function () { return chunkVDI7KYME_js.getFAQData; }
26
+ get: function () { return chunkIYVJGUYX_js.getFAQData; }
27
27
  });
28
28
  Object.defineProperty(exports, "getInternalLinks", {
29
29
  enumerable: true,
30
- get: function () { return chunkVDI7KYME_js.getInternalLinks; }
30
+ get: function () { return chunkIYVJGUYX_js.getInternalLinks; }
31
31
  });
32
32
  Object.defineProperty(exports, "getManagedScripts", {
33
33
  enumerable: true,
34
- get: function () { return chunkVDI7KYME_js.getManagedScripts; }
34
+ get: function () { return chunkIYVJGUYX_js.getManagedScripts; }
35
35
  });
36
36
  Object.defineProperty(exports, "getPrimaryEntity", {
37
37
  enumerable: true,
38
- get: function () { return chunkVDI7KYME_js.getPrimaryEntity; }
38
+ get: function () { return chunkIYVJGUYX_js.getPrimaryEntity; }
39
39
  });
40
40
  Object.defineProperty(exports, "getRedirectData", {
41
41
  enumerable: true,
42
- get: function () { return chunkVDI7KYME_js.getRedirectData; }
42
+ get: function () { return chunkIYVJGUYX_js.getRedirectData; }
43
43
  });
44
44
  Object.defineProperty(exports, "getRobotsData", {
45
45
  enumerable: true,
46
- get: function () { return chunkVDI7KYME_js.getRobotsData; }
46
+ get: function () { return chunkIYVJGUYX_js.getRobotsData; }
47
47
  });
48
48
  Object.defineProperty(exports, "getSEOPageData", {
49
49
  enumerable: true,
50
- get: function () { return chunkVDI7KYME_js.getSEOPageData; }
50
+ get: function () { return chunkIYVJGUYX_js.getSEOPageData; }
51
51
  });
52
52
  Object.defineProperty(exports, "getSchemaMarkups", {
53
53
  enumerable: true,
54
- get: function () { return chunkVDI7KYME_js.getSchemaMarkups; }
54
+ get: function () { return chunkIYVJGUYX_js.getSchemaMarkups; }
55
55
  });
56
56
  Object.defineProperty(exports, "getSitemapEntries", {
57
57
  enumerable: true,
58
- get: function () { return chunkVDI7KYME_js.getSitemapEntries; }
58
+ get: function () { return chunkIYVJGUYX_js.getSitemapEntries; }
59
59
  });
60
60
  Object.defineProperty(exports, "getVisibilityScore", {
61
61
  enumerable: true,
62
- get: function () { return chunkVDI7KYME_js.getVisibilityScore; }
62
+ get: function () { return chunkIYVJGUYX_js.getVisibilityScore; }
63
63
  });
64
64
  Object.defineProperty(exports, "getVisibilitySummary", {
65
65
  enumerable: true,
66
- get: function () { return chunkVDI7KYME_js.getVisibilitySummary; }
66
+ get: function () { return chunkIYVJGUYX_js.getVisibilitySummary; }
67
67
  });
68
68
  Object.defineProperty(exports, "recordABImpression", {
69
69
  enumerable: true,
70
- get: function () { return chunkVDI7KYME_js.recordABImpression; }
70
+ get: function () { return chunkIYVJGUYX_js.recordABImpression; }
71
71
  });
72
72
  Object.defineProperty(exports, "registerSitemap", {
73
73
  enumerable: true,
74
- get: function () { return chunkVDI7KYME_js.registerSitemap; }
74
+ get: function () { return chunkIYVJGUYX_js.registerSitemap; }
75
75
  });
76
- //# sourceMappingURL=api-QUIPJJCX.js.map
77
- //# sourceMappingURL=api-QUIPJJCX.js.map
76
+ //# sourceMappingURL=api-UBHLAPUG.js.map
77
+ //# sourceMappingURL=api-UBHLAPUG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"api-UBHLAPUG.js"}
@@ -1,4 +1,4 @@
1
- export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-FQVGK746.mjs';
1
+ export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-SKHOW2CI.mjs';
2
2
  import './chunk-4XPGGLVP.mjs';
3
- //# sourceMappingURL=api-V3BA5PMX.mjs.map
4
- //# sourceMappingURL=api-V3BA5PMX.mjs.map
3
+ //# sourceMappingURL=api-XNF6Q5HO.mjs.map
4
+ //# sourceMappingURL=api-XNF6Q5HO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"api-XNF6Q5HO.mjs"}
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkVDI7KYME_js = require('./chunk-VDI7KYME.js');
3
+ var chunkIYVJGUYX_js = require('./chunk-IYVJGUYX.js');
4
4
 
5
5
  // src/seo/routing.ts
6
6
  async function getRedirect(options) {
7
7
  const { projectId, path } = options;
8
- const redirect = await chunkVDI7KYME_js.getRedirectData(projectId, path);
8
+ const redirect = await chunkIYVJGUYX_js.getRedirectData(projectId, path);
9
9
  if (!redirect) {
10
10
  return null;
11
11
  }
@@ -47,7 +47,7 @@ function parseRobotsString(robots) {
47
47
  }
48
48
  async function getRobotsDirective(options) {
49
49
  const { projectId, path } = options;
50
- const robotsString = await chunkVDI7KYME_js.getRobotsData(projectId, path);
50
+ const robotsString = await chunkIYVJGUYX_js.getRobotsData(projectId, path);
51
51
  if (!robotsString) {
52
52
  return { index: true, follow: true };
53
53
  }
@@ -55,7 +55,7 @@ async function getRobotsDirective(options) {
55
55
  }
56
56
  async function generateSitemap(options) {
57
57
  const { projectId, baseUrl, publishedOnly = true } = options;
58
- const pages = await chunkVDI7KYME_js.getSitemapEntries(projectId, { publishedOnly });
58
+ const pages = await chunkIYVJGUYX_js.getSitemapEntries(projectId, { publishedOnly });
59
59
  const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
60
60
  return pages.map((page) => ({
61
61
  path: page.path,
@@ -66,7 +66,7 @@ async function generateSitemap(options) {
66
66
  }));
67
67
  }
68
68
  async function registerLocalSitemap(options) {
69
- const { registerSitemap } = await import('./api-QUIPJJCX.js');
69
+ const { registerSitemap } = await import('./api-UBHLAPUG.js');
70
70
  let entries = options.entries || [];
71
71
  if (options.autoDiscover && entries.length === 0) {
72
72
  try {
@@ -86,7 +86,10 @@ async function registerLocalSitemap(options) {
86
86
  return { success: true, created: 0, updated: 0 };
87
87
  }
88
88
  console.log(`[Uptrade] Registering ${entries.length} sitemap entries...`);
89
- const result = await registerSitemap(entries);
89
+ const result = await registerSitemap(entries, {
90
+ optimize_meta: options.optimize_meta !== false
91
+ // Default to true
92
+ });
90
93
  if (result.success) {
91
94
  console.log(`[Uptrade] Sitemap registered: ${result.created} new, ${result.updated} updated`);
92
95
  }
@@ -136,5 +139,5 @@ exports.getRedirect = getRedirect;
136
139
  exports.getRobotsDirective = getRobotsDirective;
137
140
  exports.isIndexable = isIndexable;
138
141
  exports.registerLocalSitemap = registerLocalSitemap;
139
- //# sourceMappingURL=chunk-QQB4FO4Q.js.map
140
- //# sourceMappingURL=chunk-QQB4FO4Q.js.map
142
+ //# sourceMappingURL=chunk-AWAJEIZS.js.map
143
+ //# sourceMappingURL=chunk-AWAJEIZS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/seo/routing.ts"],"names":["getRedirectData","getRobotsData","getSitemapEntries"],"mappings":"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","file":"chunk-AWAJEIZS.js","sourcesContent":["import { getRedirectData, getRobotsData, getSitemapEntries } from './api'\nimport type { \n GetRedirectOptions, \n RedirectResult, \n GetRobotsOptions, \n RobotsDirective,\n GetSitemapEntriesOptions,\n SitemapEntry \n} from './types'\n\n/**\n * Get redirect for a path if one exists\n * \n * Use in Next.js middleware to handle managed redirects\n * \n * @example\n * ```tsx\n * // middleware.ts\n * import { getRedirect } from '@uptrade/seo'\n * \n * export async function middleware(request) {\n * const redirect = await getRedirect({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: request.nextUrl.pathname\n * })\n * \n * if (redirect) {\n * return NextResponse.redirect(redirect.destination, redirect.statusCode)\n * }\n * }\n * ```\n */\nexport async function getRedirect(\n options: GetRedirectOptions\n): Promise<RedirectResult | null> {\n const { projectId, path } = options\n\n const redirect = await getRedirectData(projectId, path)\n\n if (!redirect) {\n return null\n }\n\n // Check if expired\n if (redirect.expires_at && new Date(redirect.expires_at) < new Date()) {\n return null\n }\n\n // Determine destination\n const destination = redirect.destination_url || redirect.destination_path\n const isExternal = destination.startsWith('http://') || destination.startsWith('https://')\n\n return {\n destination,\n statusCode: redirect.status_code,\n isExternal,\n }\n}\n\n/**\n * Parse robots directive string into structured object\n */\nfunction parseRobotsString(robots: string): RobotsDirective {\n const directive: RobotsDirective = {\n index: true,\n follow: true,\n }\n\n const parts = robots.toLowerCase().split(',').map(p => p.trim())\n\n for (const part of parts) {\n if (part === 'noindex') directive.index = false\n if (part === 'nofollow') directive.follow = false\n if (part === 'noarchive') directive.noarchive = true\n if (part === 'nosnippet') directive.nosnippet = true\n if (part === 'noimageindex') directive.noimageindex = true\n if (part.startsWith('max-snippet:')) {\n directive.max_snippet = parseInt(part.split(':')[1], 10)\n }\n if (part.startsWith('max-image-preview:')) {\n const value = part.split(':')[1] as 'none' | 'standard' | 'large'\n directive.max_image_preview = value\n }\n if (part.startsWith('max-video-preview:')) {\n directive.max_video_preview = parseInt(part.split(':')[1], 10)\n }\n }\n\n return directive\n}\n\n/**\n * Get robots directive for a page\n * \n * @example\n * ```tsx\n * const robots = await getRobotsDirective({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: '/private-page'\n * })\n * \n * if (!robots.index) {\n * // Page should not be indexed\n * }\n * ```\n */\nexport async function getRobotsDirective(\n options: GetRobotsOptions\n): Promise<RobotsDirective> {\n const { projectId, path } = options\n\n const robotsString = await getRobotsData(projectId, path)\n\n if (!robotsString) {\n // Default: index and follow\n return { index: true, follow: true }\n }\n\n return parseRobotsString(robotsString)\n}\n\n/**\n * Get sitemap entries for a project\n * \n * Use in sitemap.ts to generate dynamic sitemap\n * \n * @example\n * ```tsx\n * // app/sitemap.ts\n * import { generateSitemap } from '@uptrade/seo'\n * \n * export default async function sitemap() {\n * return generateSitemap({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * baseUrl: 'https://example.com',\n * publishedOnly: true\n * })\n * }\n * ```\n */\nexport async function generateSitemap(\n options: GetSitemapEntriesOptions\n): Promise<SitemapEntry[]> {\n const { projectId, baseUrl, publishedOnly = true } = options\n\n const pages = await getSitemapEntries(projectId, { publishedOnly })\n\n const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n\n return pages.map(page => ({\n path: page.path,\n url: `${normalizedBase}${page.path}`,\n lastmod: page.updated_at,\n changefreq: page.sitemap_changefreq || 'weekly',\n priority: page.sitemap_priority || 0.5,\n }))\n}\n\n/**\n * Register local sitemap entries with Uptrade Portal\n * \n * Call this at build time to sync your local routes to seo_pages.\n * This ensures analytics only tracks real pages.\n * \n * After registration, Signal AI will generate optimized meta titles\n * and descriptions for pages that don't have managed meta yet.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts\n * import { registerLocalSitemap } from '@uptrade/seo'\n * \n * // Option 1: Provide entries directly\n * await registerLocalSitemap({\n * entries: [\n * { path: '/', title: 'Home', priority: 1.0 },\n * { path: '/about', title: 'About Us', priority: 0.8 },\n * ]\n * })\n * \n * // Option 2: Auto-discover from Next.js app directory\n * await registerLocalSitemap({ autoDiscover: true })\n * \n * // Option 3: Skip Signal AI meta optimization\n * await registerLocalSitemap({ autoDiscover: true, optimize_meta: false })\n * ```\n */\nexport async function registerLocalSitemap(options: {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n autoDiscover?: boolean\n /** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */\n optimize_meta?: boolean\n}): Promise<{ \n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}> {\n const { registerSitemap } = await import('./api')\n \n let entries = options.entries || []\n \n // Auto-discover from Next.js app directory if requested\n if (options.autoDiscover && entries.length === 0) {\n try {\n const fs = await import('fs')\n const path = await import('path')\n \n const appDir = path.join(process.cwd(), 'app')\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir, fs, path)\n console.log(`[Uptrade] Auto-discovered ${entries.length} routes from app directory`)\n }\n } catch (error) {\n console.error('[Uptrade] Auto-discovery failed:', error)\n }\n }\n \n if (entries.length === 0) {\n console.warn('[Uptrade] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n \n console.log(`[Uptrade] Registering ${entries.length} sitemap entries...`)\n const result = await registerSitemap(entries, { \n optimize_meta: options.optimize_meta !== false, // Default to true\n })\n \n if (result.success) {\n console.log(`[Uptrade] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n \n return result\n}\n\n/**\n * Discover routes from Next.js app directory\n */\nfunction discoverNextJsRoutes(\n appDir: string,\n fs: typeof import('fs'),\n path: typeof import('path'),\n basePath: string = ''\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n \n const items = fs.readdirSync(appDir, { withFileTypes: true })\n \n for (const item of items) {\n // Skip private folders, api routes, and special files\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n \n const itemPath = path.join(appDir, item.name)\n \n if (item.isDirectory()) {\n // Check for page.tsx/page.js in this directory\n const hasPage = fs.existsSync(path.join(itemPath, 'page.tsx')) ||\n fs.existsSync(path.join(itemPath, 'page.js')) ||\n fs.existsSync(path.join(itemPath, 'page.jsx'))\n \n // Handle route groups (parentheses)\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n \n // Handle dynamic segments [slug]\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n \n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n \n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n \n // Recurse into subdirectories (but not dynamic ones)\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(itemPath, fs, path, isRouteGroup ? basePath : routePath)\n entries.push(...subEntries)\n }\n }\n }\n \n // Add root if app/page.tsx exists and we're at root\n if (basePath === '') {\n const hasRootPage = fs.existsSync(path.join(appDir, 'page.tsx')) ||\n fs.existsSync(path.join(appDir, 'page.js')) ||\n fs.existsSync(path.join(appDir, 'page.jsx'))\n if (hasRootPage) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n \n return entries\n}\n\n/**\n * Check if a path should be indexed\n * \n * Quick helper to check indexability without full directive parsing\n */\nexport async function isIndexable(\n projectId: string,\n path: string\n): Promise<boolean> {\n const directive = await getRobotsDirective({ projectId, path })\n return directive.index\n}\n"]}