@uptrademedia/site-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +305 -0
  2. package/dist/analytics/index.js +88 -0
  3. package/dist/analytics/index.js.map +1 -0
  4. package/dist/analytics/index.mjs +70 -0
  5. package/dist/analytics/index.mjs.map +1 -0
  6. package/dist/api-N35S3EES.js +57 -0
  7. package/dist/api-N35S3EES.js.map +1 -0
  8. package/dist/api-SYBTK7Z7.mjs +4 -0
  9. package/dist/api-SYBTK7Z7.mjs.map +1 -0
  10. package/dist/blog/index.js +200 -0
  11. package/dist/blog/index.js.map +1 -0
  12. package/dist/blog/index.mjs +194 -0
  13. package/dist/blog/index.mjs.map +1 -0
  14. package/dist/chunk-3MUOUXHV.js +3721 -0
  15. package/dist/chunk-3MUOUXHV.js.map +1 -0
  16. package/dist/chunk-4HVYXYQL 2.mjs +255 -0
  17. package/dist/chunk-4HVYXYQL.mjs +255 -0
  18. package/dist/chunk-4HVYXYQL.mjs.map +1 -0
  19. package/dist/chunk-7H6I3ECV.mjs +120 -0
  20. package/dist/chunk-7H6I3ECV.mjs.map +1 -0
  21. package/dist/chunk-COI6GOX2.mjs +3679 -0
  22. package/dist/chunk-COI6GOX2.mjs.map +1 -0
  23. package/dist/chunk-EQCVQC35.js +35 -0
  24. package/dist/chunk-EQCVQC35.js 2.map +1 -0
  25. package/dist/chunk-EQCVQC35.js.map +1 -0
  26. package/dist/chunk-FEBYQGY4 2.mjs +251 -0
  27. package/dist/chunk-FEBYQGY4.mjs +251 -0
  28. package/dist/chunk-FEBYQGY4.mjs.map +1 -0
  29. package/dist/chunk-FKVJOT2F.mjs +796 -0
  30. package/dist/chunk-FKVJOT2F.mjs.map +1 -0
  31. package/dist/chunk-GQ6ZOU2N.mjs +134 -0
  32. package/dist/chunk-GQ6ZOU2N.mjs.map +1 -0
  33. package/dist/chunk-HCFPU7TU.js +137 -0
  34. package/dist/chunk-HCFPU7TU.js.map +1 -0
  35. package/dist/chunk-NYKRE2FL 2.mjs +31 -0
  36. package/dist/chunk-NYKRE2FL.mjs +31 -0
  37. package/dist/chunk-NYKRE2FL.mjs 2.map +1 -0
  38. package/dist/chunk-NYKRE2FL.mjs.map +1 -0
  39. package/dist/chunk-QP5NCO2E.js +133 -0
  40. package/dist/chunk-QP5NCO2E.js.map +1 -0
  41. package/dist/chunk-RV7H3I6J.js +255 -0
  42. package/dist/chunk-RV7H3I6J.js 2.map +1 -0
  43. package/dist/chunk-RV7H3I6J.js.map +1 -0
  44. package/dist/chunk-SBVEYCSV.js +140 -0
  45. package/dist/chunk-SBVEYCSV.js.map +1 -0
  46. package/dist/chunk-TUKGA3UK.js +257 -0
  47. package/dist/chunk-TUKGA3UK.js 2.map +1 -0
  48. package/dist/chunk-TUKGA3UK.js.map +1 -0
  49. package/dist/chunk-V3F5J6CV.js +801 -0
  50. package/dist/chunk-V3F5J6CV.js.map +1 -0
  51. package/dist/chunk-WPSRS352.mjs +135 -0
  52. package/dist/chunk-WPSRS352.mjs.map +1 -0
  53. package/dist/commerce/index.js +157 -0
  54. package/dist/commerce/index.js.map +1 -0
  55. package/dist/commerce/index.mjs +4 -0
  56. package/dist/commerce/index.mjs.map +1 -0
  57. package/dist/commerce/server.js +186 -0
  58. package/dist/commerce/server.js.map +1 -0
  59. package/dist/commerce/server.mjs +176 -0
  60. package/dist/commerce/server.mjs.map +1 -0
  61. package/dist/engage/index.js +50 -0
  62. package/dist/engage/index.js.map +1 -0
  63. package/dist/engage/index.mjs +44 -0
  64. package/dist/engage/index.mjs.map +1 -0
  65. package/dist/forms/index.js +1053 -0
  66. package/dist/forms/index.js.map +1 -0
  67. package/dist/forms/index.mjs +1035 -0
  68. package/dist/forms/index.mjs.map +1 -0
  69. package/dist/generators-7Y5ABRYV 2.mjs +161 -0
  70. package/dist/generators-7Y5ABRYV.mjs +161 -0
  71. package/dist/generators-7Y5ABRYV.mjs 2.map +1 -0
  72. package/dist/generators-7Y5ABRYV.mjs.map +1 -0
  73. package/dist/generators-GWIYCA5M.js +171 -0
  74. package/dist/generators-GWIYCA5M.js 2.map +1 -0
  75. package/dist/generators-GWIYCA5M.js.map +1 -0
  76. package/dist/index 2.mjs +74 -0
  77. package/dist/index.js +326 -0
  78. package/dist/index.js 2.map +1 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/index.mjs +222 -0
  81. package/dist/index.mjs.map +1 -0
  82. package/dist/migrator-V6KS75EA 2.mjs +265 -0
  83. package/dist/migrator-V6KS75EA.mjs +265 -0
  84. package/dist/migrator-V6KS75EA.mjs 2.map +1 -0
  85. package/dist/migrator-V6KS75EA.mjs.map +1 -0
  86. package/dist/migrator-XKM7YQCY.js +272 -0
  87. package/dist/migrator-XKM7YQCY.js 2.map +1 -0
  88. package/dist/migrator-XKM7YQCY.js.map +1 -0
  89. package/dist/scanner-MF7P3CDE 2.mjs +14386 -0
  90. package/dist/scanner-MF7P3CDE.mjs +14386 -0
  91. package/dist/scanner-MF7P3CDE.mjs 2.map +1 -0
  92. package/dist/scanner-MF7P3CDE.mjs.map +1 -0
  93. package/dist/scanner-NT6YG4TD 2.js +14397 -0
  94. package/dist/scanner-NT6YG4TD.js +14397 -0
  95. package/dist/scanner-NT6YG4TD.js 2.map +1 -0
  96. package/dist/scanner-NT6YG4TD.js.map +1 -0
  97. package/dist/seo/index.js +447 -0
  98. package/dist/seo/index.js.map +1 -0
  99. package/dist/seo/index.mjs +411 -0
  100. package/dist/seo/index.mjs.map +1 -0
  101. package/dist/seo/server.js +66 -0
  102. package/dist/seo/server.js.map +1 -0
  103. package/dist/seo/server.mjs +5 -0
  104. package/dist/seo/server.mjs.map +1 -0
  105. package/dist/setup/index.js +1050 -0
  106. package/dist/setup/index.js.map +1 -0
  107. package/dist/setup/index.mjs +1046 -0
  108. package/dist/setup/index.mjs.map +1 -0
  109. package/dist/sitemap/index.js +212 -0
  110. package/dist/sitemap/index.js.map +1 -0
  111. package/dist/sitemap/index.mjs +206 -0
  112. package/dist/sitemap/index.mjs.map +1 -0
  113. package/dist/web-vitals-BH55V7EJ.js +252 -0
  114. package/dist/web-vitals-BH55V7EJ.js 2.map +1 -0
  115. package/dist/web-vitals-BH55V7EJ.js.map +1 -0
  116. package/dist/web-vitals-RJYPWAR3 2.mjs +241 -0
  117. package/dist/web-vitals-RJYPWAR3.mjs +241 -0
  118. package/dist/web-vitals-RJYPWAR3.mjs 2.map +1 -0
  119. package/dist/web-vitals-RJYPWAR3.mjs.map +1 -0
  120. package/package.json +118 -0
@@ -0,0 +1,171 @@
1
+ 'use strict';
2
+
3
+ require('./chunk-EQCVQC35.js');
4
+ var fs = require('fs/promises');
5
+ var path = require('path');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
10
+ var path__default = /*#__PURE__*/_interopDefault(path);
11
+
12
+ async function generateEnvFile(options) {
13
+ const envPath = path__default.default.join(process.cwd(), ".env.local");
14
+ let existingContent = "";
15
+ try {
16
+ existingContent = await fs__default.default.readFile(envPath, "utf-8");
17
+ } catch {
18
+ }
19
+ const newVars = {
20
+ "NEXT_PUBLIC_UPTRADE_PROJECT_ID": options.projectId,
21
+ "NEXT_PUBLIC_SUPABASE_URL": options.supabaseUrl,
22
+ "NEXT_PUBLIC_SUPABASE_ANON_KEY": options.supabaseAnonKey,
23
+ "UPTRADE_API_KEY": options.apiKey
24
+ };
25
+ const lines = existingContent.split("\n");
26
+ const existingVars = {};
27
+ for (const line of lines) {
28
+ if (line.startsWith("#") || line.trim() === "") {
29
+ continue;
30
+ }
31
+ const [key, ...valueParts] = line.split("=");
32
+ if (key) {
33
+ existingVars[key.trim()] = valueParts.join("=").trim();
34
+ }
35
+ }
36
+ let newContent = `# Uptrade Site-Kit Configuration
37
+ # Generated by @uptrade/site-kit setup wizard
38
+
39
+ # Project ID from Uptrade Portal
40
+ NEXT_PUBLIC_UPTRADE_PROJECT_ID=${newVars["NEXT_PUBLIC_UPTRADE_PROJECT_ID"]}
41
+
42
+ # Supabase Configuration
43
+ NEXT_PUBLIC_SUPABASE_URL=${newVars["NEXT_PUBLIC_SUPABASE_URL"]}
44
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=${newVars["NEXT_PUBLIC_SUPABASE_ANON_KEY"]}
45
+
46
+ # Uptrade API Key (for server-side operations)
47
+ UPTRADE_API_KEY=${newVars["UPTRADE_API_KEY"]}
48
+
49
+ `;
50
+ const uptradeKeys = Object.keys(newVars);
51
+ const otherVars = Object.entries(existingVars).filter(([key]) => !uptradeKeys.includes(key));
52
+ if (otherVars.length > 0) {
53
+ newContent += "# Other Environment Variables\n";
54
+ for (const [key, value] of otherVars) {
55
+ newContent += `${key}=${value}
56
+ `;
57
+ }
58
+ }
59
+ await fs__default.default.writeFile(envPath, newContent, "utf-8");
60
+ }
61
+ async function generateProvider(options) {
62
+ const layoutPath = await findLayoutFile();
63
+ if (!layoutPath) {
64
+ throw new Error("Could not find layout.tsx file");
65
+ }
66
+ const content = await fs__default.default.readFile(layoutPath, "utf-8");
67
+ if (content.includes("SiteKitProvider")) {
68
+ return;
69
+ }
70
+ let newContent = content;
71
+ const lastImportIndex = content.lastIndexOf("import ");
72
+ const lastImportEndIndex = content.indexOf("\n", lastImportIndex);
73
+ const importStatement = `
74
+ import { SiteKitProvider } from '@uptrade/site-kit'`;
75
+ newContent = content.slice(0, lastImportEndIndex) + importStatement + content.slice(lastImportEndIndex);
76
+ const childrenPattern = /(\s*){children}/;
77
+ const childrenMatch = newContent.match(childrenPattern);
78
+ if (childrenMatch) {
79
+ const indent = childrenMatch[1] || " ";
80
+ const providerWrap = `
81
+ ${indent}<SiteKitProvider
82
+ ${indent} projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
83
+ ${indent} supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}
84
+ ${indent} supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}
85
+ ${indent} analytics={{ enabled: true }}
86
+ ${indent} engage={{ enabled: true }}
87
+ ${indent} forms={{ enabled: true }}
88
+ ${indent}>
89
+ ${indent} {children}
90
+ ${indent}</SiteKitProvider>`;
91
+ newContent = newContent.replace(childrenPattern, providerWrap);
92
+ } else {
93
+ const bodyPattern = /(<body[^>]*>)([\s\S]*?)(<\/body>)/;
94
+ const bodyMatch = newContent.match(bodyPattern);
95
+ if (bodyMatch) {
96
+ const bodyContent = bodyMatch[2];
97
+ const wrappedContent = `
98
+ <SiteKitProvider
99
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
100
+ supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}
101
+ supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}
102
+ analytics={{ enabled: true }}
103
+ engage={{ enabled: true }}
104
+ forms={{ enabled: true }}
105
+ >
106
+ ${bodyContent.trim()}
107
+ </SiteKitProvider>
108
+ `;
109
+ newContent = newContent.replace(bodyPattern, `$1${wrappedContent}$3`);
110
+ }
111
+ }
112
+ await fs__default.default.writeFile(layoutPath, newContent, "utf-8");
113
+ }
114
+ async function findLayoutFile() {
115
+ const possiblePaths = [
116
+ "src/app/layout.tsx",
117
+ "app/layout.tsx",
118
+ "src/app/layout.jsx",
119
+ "app/layout.jsx"
120
+ ];
121
+ for (const relativePath of possiblePaths) {
122
+ const fullPath = path__default.default.join(process.cwd(), relativePath);
123
+ try {
124
+ await fs__default.default.access(fullPath);
125
+ return fullPath;
126
+ } catch {
127
+ continue;
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ async function generateSetupRoute() {
133
+ const routeDir = path__default.default.join(process.cwd(), "app", "_uptrade", "setup");
134
+ await fs__default.default.mkdir(routeDir, { recursive: true });
135
+ const pageContent = `/**
136
+ * Uptrade Setup Wizard
137
+ *
138
+ * This route is automatically removed after setup is complete.
139
+ * Visit /_uptrade/setup to configure Site-Kit.
140
+ */
141
+
142
+ import { SetupWizard } from '@uptrade/site-kit/setup'
143
+
144
+ export default function SetupPage() {
145
+ return <SetupWizard />
146
+ }
147
+ `;
148
+ await fs__default.default.writeFile(path__default.default.join(routeDir, "page.tsx"), pageContent, "utf-8");
149
+ }
150
+ async function selfDestruct() {
151
+ const setupDir = path__default.default.join(process.cwd(), "app", "_uptrade");
152
+ try {
153
+ await fs__default.default.rm(setupDir, { recursive: true, force: true });
154
+ } catch {
155
+ }
156
+ const layoutPath = await findLayoutFile();
157
+ if (layoutPath) {
158
+ let content = await fs__default.default.readFile(layoutPath, "utf-8");
159
+ content = content.replace(/import\s*{\s*UptradeSetup\s*}\s*from\s*['"]@uptrade\/site-kit\/setup['"][;\n]?/g, "");
160
+ content = content.replace(/\s*{process\.env\.NODE_ENV\s*===\s*['"]development['"]\s*&&\s*<UptradeSetup\s*\/>}\s*/g, "\n");
161
+ content = content.replace(/<UptradeSetup\s*\/>/g, "");
162
+ await fs__default.default.writeFile(layoutPath, content, "utf-8");
163
+ }
164
+ }
165
+
166
+ exports.generateEnvFile = generateEnvFile;
167
+ exports.generateProvider = generateProvider;
168
+ exports.generateSetupRoute = generateSetupRoute;
169
+ exports.selfDestruct = selfDestruct;
170
+ //# sourceMappingURL=generators-GWIYCA5M.js.map
171
+ //# sourceMappingURL=generators-GWIYCA5M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/generators/index.ts"],"names":["path","fs"],"mappings":"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","file":"generators-GWIYCA5M.js","sourcesContent":["/**\n * Code Generators - Creates SiteKitProvider setup and env files\n */\n\nimport fs from 'fs/promises'\nimport path from 'path'\n\n// ============================================\n// Types\n// ============================================\n\ninterface EnvOptions {\n projectId: string\n supabaseUrl: string\n supabaseAnonKey: string\n apiKey: string\n}\n\ninterface ProviderOptions {\n projectId: string\n}\n\n// ============================================\n// Env File Generator\n// ============================================\n\nexport async function generateEnvFile(options: EnvOptions): Promise<void> {\n const envPath = path.join(process.cwd(), '.env.local')\n \n // Check if file exists and read existing content\n let existingContent = ''\n try {\n existingContent = await fs.readFile(envPath, 'utf-8')\n } catch {\n // File doesn't exist, that's fine\n }\n\n // Build new env vars\n const newVars: Record<string, string> = {\n 'NEXT_PUBLIC_UPTRADE_PROJECT_ID': options.projectId,\n 'NEXT_PUBLIC_SUPABASE_URL': options.supabaseUrl,\n 'NEXT_PUBLIC_SUPABASE_ANON_KEY': options.supabaseAnonKey,\n 'UPTRADE_API_KEY': options.apiKey,\n }\n\n // Parse existing content\n const lines = existingContent.split('\\n')\n const existingVars: Record<string, string> = {}\n const comments: string[] = []\n\n for (const line of lines) {\n if (line.startsWith('#') || line.trim() === '') {\n comments.push(line)\n continue\n }\n const [key, ...valueParts] = line.split('=')\n if (key) {\n existingVars[key.trim()] = valueParts.join('=').trim()\n }\n }\n\n // Merge vars (new vars take precedence)\n const mergedVars = { ...existingVars, ...newVars }\n\n // Generate new content\n let newContent = `# Uptrade Site-Kit Configuration\n# Generated by @uptrade/site-kit setup wizard\n\n# Project ID from Uptrade Portal\nNEXT_PUBLIC_UPTRADE_PROJECT_ID=${newVars['NEXT_PUBLIC_UPTRADE_PROJECT_ID']}\n\n# Supabase Configuration\nNEXT_PUBLIC_SUPABASE_URL=${newVars['NEXT_PUBLIC_SUPABASE_URL']}\nNEXT_PUBLIC_SUPABASE_ANON_KEY=${newVars['NEXT_PUBLIC_SUPABASE_ANON_KEY']}\n\n# Uptrade API Key (for server-side operations)\nUPTRADE_API_KEY=${newVars['UPTRADE_API_KEY']}\n\n`\n\n // Add any existing vars that aren't Uptrade-related\n const uptradeKeys = Object.keys(newVars)\n const otherVars = Object.entries(existingVars)\n .filter(([key]) => !uptradeKeys.includes(key))\n \n if (otherVars.length > 0) {\n newContent += '# Other Environment Variables\\n'\n for (const [key, value] of otherVars) {\n newContent += `${key}=${value}\\n`\n }\n }\n\n await fs.writeFile(envPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Provider Generator\n// ============================================\n\nexport async function generateProvider(options: ProviderOptions): Promise<void> {\n // Find the layout file\n const layoutPath = await findLayoutFile()\n if (!layoutPath) {\n throw new Error('Could not find layout.tsx file')\n }\n\n const content = await fs.readFile(layoutPath, 'utf-8')\n\n // Check if SiteKitProvider is already added\n if (content.includes('SiteKitProvider')) {\n return // Already configured\n }\n\n // Add import\n let newContent = content\n\n // Find where to add import (after other imports)\n const lastImportIndex = content.lastIndexOf('import ')\n const lastImportEndIndex = content.indexOf('\\n', lastImportIndex)\n \n const importStatement = `\\nimport { SiteKitProvider } from '@uptrade/site-kit'`\n newContent = \n content.slice(0, lastImportEndIndex) + \n importStatement + \n content.slice(lastImportEndIndex)\n\n // Wrap children with SiteKitProvider\n // Look for {children} and wrap it\n const childrenPattern = /(\\s*){children}/\n const childrenMatch = newContent.match(childrenPattern)\n \n if (childrenMatch) {\n const indent = childrenMatch[1] || ' '\n const providerWrap = `\n${indent}<SiteKitProvider\n${indent} projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n${indent} supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}\n${indent} supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}\n${indent} analytics={{ enabled: true }}\n${indent} engage={{ enabled: true }}\n${indent} forms={{ enabled: true }}\n${indent}>\n${indent} {children}\n${indent}</SiteKitProvider>`\n\n newContent = newContent.replace(childrenPattern, providerWrap)\n } else {\n // Try alternative pattern for layouts that use a different structure\n const bodyPattern = /(<body[^>]*>)([\\s\\S]*?)(<\\/body>)/\n const bodyMatch = newContent.match(bodyPattern)\n \n if (bodyMatch) {\n const bodyContent = bodyMatch[2]\n const wrappedContent = `\n <SiteKitProvider\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}\n supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}\n analytics={{ enabled: true }}\n engage={{ enabled: true }}\n forms={{ enabled: true }}\n >\n ${bodyContent.trim()}\n </SiteKitProvider>\n `\n \n newContent = newContent.replace(bodyPattern, `$1${wrappedContent}$3`)\n }\n }\n\n await fs.writeFile(layoutPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Helpers\n// ============================================\n\nasync function findLayoutFile(): Promise<string | null> {\n const possiblePaths = [\n 'src/app/layout.tsx',\n 'app/layout.tsx',\n 'src/app/layout.jsx',\n 'app/layout.jsx',\n ]\n\n for (const relativePath of possiblePaths) {\n const fullPath = path.join(process.cwd(), relativePath)\n try {\n await fs.access(fullPath)\n return fullPath\n } catch {\n continue\n }\n }\n\n return null\n}\n\n// ============================================\n// Setup Route Generator (for visual wizard)\n// ============================================\n\nexport async function generateSetupRoute(): Promise<void> {\n const routeDir = path.join(process.cwd(), 'app', '_uptrade', 'setup')\n \n // Create directory\n await fs.mkdir(routeDir, { recursive: true })\n\n // Create page.tsx\n const pageContent = `/**\n * Uptrade Setup Wizard\n * \n * This route is automatically removed after setup is complete.\n * Visit /_uptrade/setup to configure Site-Kit.\n */\n\nimport { SetupWizard } from '@uptrade/site-kit/setup'\n\nexport default function SetupPage() {\n return <SetupWizard />\n}\n`\n\n await fs.writeFile(path.join(routeDir, 'page.tsx'), pageContent, 'utf-8')\n}\n\n// ============================================\n// Self-Destruct\n// ============================================\n\nexport async function selfDestruct(): Promise<void> {\n // Remove setup route\n const setupDir = path.join(process.cwd(), 'app', '_uptrade')\n try {\n await fs.rm(setupDir, { recursive: true, force: true })\n } catch {\n // Directory might not exist\n }\n\n // Remove UptradeSetup from layout if present\n const layoutPath = await findLayoutFile()\n if (layoutPath) {\n let content = await fs.readFile(layoutPath, 'utf-8')\n \n // Remove import\n content = content.replace(/import\\s*{\\s*UptradeSetup\\s*}\\s*from\\s*['\"]@uptrade\\/site-kit\\/setup['\"][;\\n]?/g, '')\n \n // Remove component usage\n content = content.replace(/\\s*{process\\.env\\.NODE_ENV\\s*===\\s*['\"]development['\"]\\s*&&\\s*<UptradeSetup\\s*\\/>}\\s*/g, '\\n')\n content = content.replace(/<UptradeSetup\\s*\\/>/g, '')\n \n await fs.writeFile(layoutPath, content, 'utf-8')\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/generators/index.ts"],"names":["path","fs"],"mappings":"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","file":"generators-GWIYCA5M.js","sourcesContent":["/**\n * Code Generators - Creates SiteKitProvider setup and env files\n */\n\nimport fs from 'fs/promises'\nimport path from 'path'\n\n// ============================================\n// Types\n// ============================================\n\ninterface EnvOptions {\n projectId: string\n supabaseUrl: string\n supabaseAnonKey: string\n apiKey: string\n}\n\ninterface ProviderOptions {\n projectId: string\n}\n\n// ============================================\n// Env File Generator\n// ============================================\n\nexport async function generateEnvFile(options: EnvOptions): Promise<void> {\n const envPath = path.join(process.cwd(), '.env.local')\n \n // Check if file exists and read existing content\n let existingContent = ''\n try {\n existingContent = await fs.readFile(envPath, 'utf-8')\n } catch {\n // File doesn't exist, that's fine\n }\n\n // Build new env vars\n const newVars: Record<string, string> = {\n 'NEXT_PUBLIC_UPTRADE_PROJECT_ID': options.projectId,\n 'NEXT_PUBLIC_SUPABASE_URL': options.supabaseUrl,\n 'NEXT_PUBLIC_SUPABASE_ANON_KEY': options.supabaseAnonKey,\n 'UPTRADE_API_KEY': options.apiKey,\n }\n\n // Parse existing content\n const lines = existingContent.split('\\n')\n const existingVars: Record<string, string> = {}\n const comments: string[] = []\n\n for (const line of lines) {\n if (line.startsWith('#') || line.trim() === '') {\n comments.push(line)\n continue\n }\n const [key, ...valueParts] = line.split('=')\n if (key) {\n existingVars[key.trim()] = valueParts.join('=').trim()\n }\n }\n\n // Merge vars (new vars take precedence)\n const mergedVars = { ...existingVars, ...newVars }\n\n // Generate new content\n let newContent = `# Uptrade Site-Kit Configuration\n# Generated by @uptrade/site-kit setup wizard\n\n# Project ID from Uptrade Portal\nNEXT_PUBLIC_UPTRADE_PROJECT_ID=${newVars['NEXT_PUBLIC_UPTRADE_PROJECT_ID']}\n\n# Supabase Configuration\nNEXT_PUBLIC_SUPABASE_URL=${newVars['NEXT_PUBLIC_SUPABASE_URL']}\nNEXT_PUBLIC_SUPABASE_ANON_KEY=${newVars['NEXT_PUBLIC_SUPABASE_ANON_KEY']}\n\n# Uptrade API Key (for server-side operations)\nUPTRADE_API_KEY=${newVars['UPTRADE_API_KEY']}\n\n`\n\n // Add any existing vars that aren't Uptrade-related\n const uptradeKeys = Object.keys(newVars)\n const otherVars = Object.entries(existingVars)\n .filter(([key]) => !uptradeKeys.includes(key))\n \n if (otherVars.length > 0) {\n newContent += '# Other Environment Variables\\n'\n for (const [key, value] of otherVars) {\n newContent += `${key}=${value}\\n`\n }\n }\n\n await fs.writeFile(envPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Provider Generator\n// ============================================\n\nexport async function generateProvider(options: ProviderOptions): Promise<void> {\n // Find the layout file\n const layoutPath = await findLayoutFile()\n if (!layoutPath) {\n throw new Error('Could not find layout.tsx file')\n }\n\n const content = await fs.readFile(layoutPath, 'utf-8')\n\n // Check if SiteKitProvider is already added\n if (content.includes('SiteKitProvider')) {\n return // Already configured\n }\n\n // Add import\n let newContent = content\n\n // Find where to add import (after other imports)\n const lastImportIndex = content.lastIndexOf('import ')\n const lastImportEndIndex = content.indexOf('\\n', lastImportIndex)\n \n const importStatement = `\\nimport { SiteKitProvider } from '@uptrade/site-kit'`\n newContent = \n content.slice(0, lastImportEndIndex) + \n importStatement + \n content.slice(lastImportEndIndex)\n\n // Wrap children with SiteKitProvider\n // Look for {children} and wrap it\n const childrenPattern = /(\\s*){children}/\n const childrenMatch = newContent.match(childrenPattern)\n \n if (childrenMatch) {\n const indent = childrenMatch[1] || ' '\n const providerWrap = `\n${indent}<SiteKitProvider\n${indent} projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n${indent} supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}\n${indent} supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}\n${indent} analytics={{ enabled: true }}\n${indent} engage={{ enabled: true }}\n${indent} forms={{ enabled: true }}\n${indent}>\n${indent} {children}\n${indent}</SiteKitProvider>`\n\n newContent = newContent.replace(childrenPattern, providerWrap)\n } else {\n // Try alternative pattern for layouts that use a different structure\n const bodyPattern = /(<body[^>]*>)([\\s\\S]*?)(<\\/body>)/\n const bodyMatch = newContent.match(bodyPattern)\n \n if (bodyMatch) {\n const bodyContent = bodyMatch[2]\n const wrappedContent = `\n <SiteKitProvider\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n supabaseUrl={process.env.NEXT_PUBLIC_SUPABASE_URL!}\n supabaseAnonKey={process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!}\n analytics={{ enabled: true }}\n engage={{ enabled: true }}\n forms={{ enabled: true }}\n >\n ${bodyContent.trim()}\n </SiteKitProvider>\n `\n \n newContent = newContent.replace(bodyPattern, `$1${wrappedContent}$3`)\n }\n }\n\n await fs.writeFile(layoutPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Helpers\n// ============================================\n\nasync function findLayoutFile(): Promise<string | null> {\n const possiblePaths = [\n 'src/app/layout.tsx',\n 'app/layout.tsx',\n 'src/app/layout.jsx',\n 'app/layout.jsx',\n ]\n\n for (const relativePath of possiblePaths) {\n const fullPath = path.join(process.cwd(), relativePath)\n try {\n await fs.access(fullPath)\n return fullPath\n } catch {\n continue\n }\n }\n\n return null\n}\n\n// ============================================\n// Setup Route Generator (for visual wizard)\n// ============================================\n\nexport async function generateSetupRoute(): Promise<void> {\n const routeDir = path.join(process.cwd(), 'app', '_uptrade', 'setup')\n \n // Create directory\n await fs.mkdir(routeDir, { recursive: true })\n\n // Create page.tsx\n const pageContent = `/**\n * Uptrade Setup Wizard\n * \n * This route is automatically removed after setup is complete.\n * Visit /_uptrade/setup to configure Site-Kit.\n */\n\nimport { SetupWizard } from '@uptrade/site-kit/setup'\n\nexport default function SetupPage() {\n return <SetupWizard />\n}\n`\n\n await fs.writeFile(path.join(routeDir, 'page.tsx'), pageContent, 'utf-8')\n}\n\n// ============================================\n// Self-Destruct\n// ============================================\n\nexport async function selfDestruct(): Promise<void> {\n // Remove setup route\n const setupDir = path.join(process.cwd(), 'app', '_uptrade')\n try {\n await fs.rm(setupDir, { recursive: true, force: true })\n } catch {\n // Directory might not exist\n }\n\n // Remove UptradeSetup from layout if present\n const layoutPath = await findLayoutFile()\n if (layoutPath) {\n let content = await fs.readFile(layoutPath, 'utf-8')\n \n // Remove import\n content = content.replace(/import\\s*{\\s*UptradeSetup\\s*}\\s*from\\s*['\"]@uptrade\\/site-kit\\/setup['\"][;\\n]?/g, '')\n \n // Remove component usage\n content = content.replace(/\\s*{process\\.env\\.NODE_ENV\\s*===\\s*['\"]development['\"]\\s*&&\\s*<UptradeSetup\\s*\\/>}\\s*/g, '\\n')\n content = content.replace(/<UptradeSetup\\s*\\/>/g, '')\n \n await fs.writeFile(layoutPath, content, 'utf-8')\n }\n}\n"]}
@@ -0,0 +1,74 @@
1
+ import { AnalyticsProvider } from './chunk-2H32HPOI.mjs';
2
+ import { EngageWidget } from './chunk-4HVYXYQL.mjs';
3
+ import { configureFormsApi } from './chunk-FEBYQGY4.mjs';
4
+ export { CalendarView, CheckoutForm, EventCalendar, EventEmbed, EventModal, EventTile, OfferingCard, OfferingList, ProductEmbed, RegistrationForm, UpcomingEvents, createCheckoutSession, fetchNextEvent, fetchOffering, fetchOfferings, fetchProducts, fetchServices, fetchUpcomingEvents, formatDate, formatDateTime, formatPrice, getOfferingUrl, registerForEvent, useEventModal } from './chunk-HNMHZ7TQ.mjs';
5
+ import './chunk-NYKRE2FL.mjs';
6
+ import { createContext, useContext, useEffect, useMemo, Suspense } from 'react';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ var SiteKitContext = createContext(null);
10
+ function useSiteKit() {
11
+ const context = useContext(SiteKitContext);
12
+ if (!context) {
13
+ throw new Error("useSiteKit must be used within a SiteKitProvider");
14
+ }
15
+ return context;
16
+ }
17
+ function SiteKitProvider({
18
+ children,
19
+ apiUrl = "https://api.uptrademedia.com",
20
+ apiKey,
21
+ analytics,
22
+ engage,
23
+ forms,
24
+ debug = false
25
+ }) {
26
+ useEffect(() => {
27
+ if (typeof window !== "undefined") {
28
+ window.__SITE_KIT_API_URL__ = apiUrl;
29
+ window.__SITE_KIT_API_KEY__ = apiKey;
30
+ window.__SITE_KIT_DEBUG__ = debug;
31
+ }
32
+ configureFormsApi({
33
+ baseUrl: apiUrl,
34
+ apiKey
35
+ });
36
+ }, [apiUrl, apiKey, debug]);
37
+ const contextValue = useMemo(
38
+ () => ({
39
+ apiUrl,
40
+ apiKey,
41
+ analytics,
42
+ engage,
43
+ forms,
44
+ debug,
45
+ isReady: true
46
+ }),
47
+ [apiUrl, apiKey, analytics, engage, forms, debug]
48
+ );
49
+ let content = /* @__PURE__ */ jsx(Fragment, { children });
50
+ if (analytics?.enabled) {
51
+ content = /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
52
+ AnalyticsProvider,
53
+ {
54
+ apiUrl,
55
+ apiKey,
56
+ trackPageViews: analytics.trackPageViews !== false,
57
+ trackWebVitals: analytics.trackWebVitals !== false,
58
+ debug,
59
+ children: content
60
+ }
61
+ ) });
62
+ }
63
+ if (engage?.enabled) {
64
+ content = /* @__PURE__ */ jsxs(Fragment, { children: [
65
+ content,
66
+ /* @__PURE__ */ jsx(EngageWidget, { apiUrl, apiKey })
67
+ ] });
68
+ }
69
+ return /* @__PURE__ */ jsx(SiteKitContext.Provider, { value: contextValue, children: content });
70
+ }
71
+
72
+ export { SiteKitProvider, useSiteKit };
73
+ //# sourceMappingURL=index.mjs.map
74
+ //# sourceMappingURL=index.mjs.map
package/dist/index.js ADDED
@@ -0,0 +1,326 @@
1
+ 'use strict';
2
+
3
+ var chunkHCFPU7TU_js = require('./chunk-HCFPU7TU.js');
4
+ var chunkV3F5J6CV_js = require('./chunk-V3F5J6CV.js');
5
+ var chunkTUKGA3UK_js = require('./chunk-TUKGA3UK.js');
6
+ var chunkRV7H3I6J_js = require('./chunk-RV7H3I6J.js');
7
+ var chunk3MUOUXHV_js = require('./chunk-3MUOUXHV.js');
8
+ require('./chunk-EQCVQC35.js');
9
+ var react = require('react');
10
+ var jsxRuntime = require('react/jsx-runtime');
11
+
12
+ var SiteKitContext = react.createContext(null);
13
+ function useSiteKit() {
14
+ const context = react.useContext(SiteKitContext);
15
+ if (!context) {
16
+ throw new Error("useSiteKit must be used within a SiteKitProvider");
17
+ }
18
+ return context;
19
+ }
20
+ function SiteKitProvider({
21
+ children,
22
+ apiUrl = "https://api.uptrademedia.com",
23
+ apiKey,
24
+ analytics,
25
+ engage,
26
+ forms,
27
+ debug = false
28
+ }) {
29
+ react.useEffect(() => {
30
+ if (typeof window !== "undefined") {
31
+ window.__SITE_KIT_API_URL__ = apiUrl;
32
+ window.__SITE_KIT_API_KEY__ = apiKey;
33
+ window.__SITE_KIT_DEBUG__ = debug;
34
+ }
35
+ chunkRV7H3I6J_js.configureFormsApi({
36
+ baseUrl: apiUrl,
37
+ apiKey
38
+ });
39
+ }, [apiUrl, apiKey, debug]);
40
+ const contextValue = react.useMemo(
41
+ () => ({
42
+ apiUrl,
43
+ apiKey,
44
+ analytics,
45
+ engage,
46
+ forms,
47
+ debug,
48
+ isReady: true
49
+ }),
50
+ [apiUrl, apiKey, analytics, engage, forms, debug]
51
+ );
52
+ let content = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
53
+ if (analytics?.enabled) {
54
+ content = /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
55
+ chunkV3F5J6CV_js.AnalyticsProvider,
56
+ {
57
+ apiUrl,
58
+ apiKey,
59
+ trackPageViews: analytics.trackPageViews !== false,
60
+ trackWebVitals: analytics.trackWebVitals !== false,
61
+ trackScrollDepth: analytics.trackScrollDepth !== false,
62
+ trackClicks: analytics.trackClicks !== false,
63
+ debug,
64
+ children: content
65
+ }
66
+ ) });
67
+ }
68
+ if (engage?.enabled) {
69
+ content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
70
+ content,
71
+ /* @__PURE__ */ jsxRuntime.jsx(chunkTUKGA3UK_js.EngageWidget, { apiUrl, apiKey })
72
+ ] });
73
+ }
74
+ content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
75
+ content,
76
+ /* @__PURE__ */ jsxRuntime.jsx(chunkHCFPU7TU_js.SitemapSync, { debug })
77
+ ] });
78
+ return /* @__PURE__ */ jsxRuntime.jsx(SiteKitContext.Provider, { value: contextValue, children: content });
79
+ }
80
+
81
+ // src/affiliates/api.ts
82
+ function getApiConfig() {
83
+ const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || "https://api.uptrademedia.com" : "https://api.uptrademedia.com";
84
+ const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ || "" : "";
85
+ return { apiUrl, apiKey };
86
+ }
87
+ async function apiGet(endpoint) {
88
+ const { apiUrl, apiKey } = getApiConfig();
89
+ if (!apiKey) {
90
+ console.error("[Affiliates] No API key configured");
91
+ return null;
92
+ }
93
+ try {
94
+ const response = await fetch(`${apiUrl}${endpoint}`, {
95
+ method: "GET",
96
+ headers: {
97
+ "x-api-key": apiKey
98
+ }
99
+ });
100
+ if (!response.ok) {
101
+ console.error(`[Affiliates] API error: ${response.statusText}`);
102
+ return null;
103
+ }
104
+ return await response.json();
105
+ } catch (error) {
106
+ console.error("[Affiliates] Network error:", error);
107
+ return null;
108
+ }
109
+ }
110
+ async function fetchAffiliates(options = {}) {
111
+ const result = await apiGet(
112
+ "/api/public/affiliates"
113
+ );
114
+ return result?.affiliates || [];
115
+ }
116
+ function getTrackingUrl(affiliateId, offerId) {
117
+ const { apiUrl } = getApiConfig();
118
+ return `${apiUrl}/a/${affiliateId}/${offerId}`;
119
+ }
120
+ function useAffiliates() {
121
+ const [affiliates, setAffiliates] = react.useState([]);
122
+ const [isLoading, setIsLoading] = react.useState(true);
123
+ const [error, setError] = react.useState(null);
124
+ react.useEffect(() => {
125
+ async function load() {
126
+ try {
127
+ setIsLoading(true);
128
+ setError(null);
129
+ const data = await fetchAffiliates();
130
+ setAffiliates(data);
131
+ } catch (err) {
132
+ setError(err instanceof Error ? err.message : "Failed to load affiliates");
133
+ } finally {
134
+ setIsLoading(false);
135
+ }
136
+ }
137
+ load();
138
+ }, []);
139
+ return {
140
+ affiliates,
141
+ isLoading,
142
+ error,
143
+ getTrackingUrl
144
+ };
145
+ }
146
+ function AffiliateCard({
147
+ affiliate,
148
+ className = "",
149
+ renderLogo,
150
+ showOffers = false
151
+ }) {
152
+ const { getTrackingUrl: getTrackingUrl2 } = useAffiliates();
153
+ const defaultLogo = /* @__PURE__ */ jsxRuntime.jsx("div", { "data-affiliate-logo": true, className: "affiliate-logo", children: affiliate.logo_url ? /* @__PURE__ */ jsxRuntime.jsx(
154
+ "img",
155
+ {
156
+ src: affiliate.logo_url,
157
+ alt: affiliate.name,
158
+ loading: "lazy"
159
+ }
160
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: affiliate.name.charAt(0) }) });
161
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-affiliate-card": true, "data-affiliate-id": affiliate.id, children: [
162
+ renderLogo ? renderLogo(affiliate) : defaultLogo,
163
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-affiliate-name": true, className: "affiliate-name", children: affiliate.name }),
164
+ affiliate.website_url && /* @__PURE__ */ jsxRuntime.jsx(
165
+ "a",
166
+ {
167
+ href: affiliate.website_url,
168
+ target: "_blank",
169
+ rel: "noopener noreferrer sponsored",
170
+ "data-affiliate-website": true,
171
+ className: "affiliate-website",
172
+ children: "Visit Website"
173
+ }
174
+ ),
175
+ showOffers && affiliate.offers && affiliate.offers.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-affiliate-offers": true, className: "affiliate-offers", children: affiliate.offers.map((offer) => /* @__PURE__ */ jsxRuntime.jsx(
176
+ "a",
177
+ {
178
+ href: getTrackingUrl2(affiliate.id, offer.id),
179
+ target: "_blank",
180
+ rel: "noopener noreferrer sponsored",
181
+ "data-affiliate-offer": true,
182
+ "data-offer-id": offer.id,
183
+ className: "affiliate-offer",
184
+ children: offer.name
185
+ },
186
+ offer.id
187
+ )) })
188
+ ] });
189
+ }
190
+ function AffiliatesWidget({
191
+ className = "",
192
+ loadingComponent,
193
+ emptyComponent,
194
+ errorComponent,
195
+ showOffers = false,
196
+ renderAffiliate,
197
+ limit
198
+ }) {
199
+ const { affiliates, isLoading, error, getTrackingUrl: getTrackingUrl2 } = useAffiliates();
200
+ if (isLoading) {
201
+ return loadingComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { "data-affiliates-loading": true, children: "Loading affiliates..." });
202
+ }
203
+ if (error) {
204
+ return errorComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { "data-affiliates-error": true, children: error });
205
+ }
206
+ const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates;
207
+ if (displayAffiliates.length === 0) {
208
+ return emptyComponent || null;
209
+ }
210
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-affiliates-widget": true, children: displayAffiliates.map(
211
+ (affiliate) => renderAffiliate ? renderAffiliate(affiliate) : /* @__PURE__ */ jsxRuntime.jsx(
212
+ AffiliateCard,
213
+ {
214
+ affiliate,
215
+ showOffers
216
+ },
217
+ affiliate.id
218
+ )
219
+ ) });
220
+ }
221
+
222
+ Object.defineProperty(exports, "CalendarView", {
223
+ enumerable: true,
224
+ get: function () { return chunk3MUOUXHV_js.CalendarView; }
225
+ });
226
+ Object.defineProperty(exports, "CheckoutForm", {
227
+ enumerable: true,
228
+ get: function () { return chunk3MUOUXHV_js.CheckoutForm; }
229
+ });
230
+ Object.defineProperty(exports, "EventCalendar", {
231
+ enumerable: true,
232
+ get: function () { return chunk3MUOUXHV_js.EventCalendar; }
233
+ });
234
+ Object.defineProperty(exports, "EventEmbed", {
235
+ enumerable: true,
236
+ get: function () { return chunk3MUOUXHV_js.EventEmbed; }
237
+ });
238
+ Object.defineProperty(exports, "EventModal", {
239
+ enumerable: true,
240
+ get: function () { return chunk3MUOUXHV_js.EventModal; }
241
+ });
242
+ Object.defineProperty(exports, "EventTile", {
243
+ enumerable: true,
244
+ get: function () { return chunk3MUOUXHV_js.EventTile; }
245
+ });
246
+ Object.defineProperty(exports, "OfferingCard", {
247
+ enumerable: true,
248
+ get: function () { return chunk3MUOUXHV_js.OfferingCard; }
249
+ });
250
+ Object.defineProperty(exports, "OfferingList", {
251
+ enumerable: true,
252
+ get: function () { return chunk3MUOUXHV_js.OfferingList; }
253
+ });
254
+ Object.defineProperty(exports, "ProductEmbed", {
255
+ enumerable: true,
256
+ get: function () { return chunk3MUOUXHV_js.ProductEmbed; }
257
+ });
258
+ Object.defineProperty(exports, "RegistrationForm", {
259
+ enumerable: true,
260
+ get: function () { return chunk3MUOUXHV_js.RegistrationForm; }
261
+ });
262
+ Object.defineProperty(exports, "UpcomingEvents", {
263
+ enumerable: true,
264
+ get: function () { return chunk3MUOUXHV_js.UpcomingEvents; }
265
+ });
266
+ Object.defineProperty(exports, "createCheckoutSession", {
267
+ enumerable: true,
268
+ get: function () { return chunk3MUOUXHV_js.createCheckoutSession; }
269
+ });
270
+ Object.defineProperty(exports, "fetchNextEvent", {
271
+ enumerable: true,
272
+ get: function () { return chunk3MUOUXHV_js.fetchNextEvent; }
273
+ });
274
+ Object.defineProperty(exports, "fetchOffering", {
275
+ enumerable: true,
276
+ get: function () { return chunk3MUOUXHV_js.fetchOffering; }
277
+ });
278
+ Object.defineProperty(exports, "fetchOfferings", {
279
+ enumerable: true,
280
+ get: function () { return chunk3MUOUXHV_js.fetchOfferings; }
281
+ });
282
+ Object.defineProperty(exports, "fetchProducts", {
283
+ enumerable: true,
284
+ get: function () { return chunk3MUOUXHV_js.fetchProducts; }
285
+ });
286
+ Object.defineProperty(exports, "fetchServices", {
287
+ enumerable: true,
288
+ get: function () { return chunk3MUOUXHV_js.fetchServices; }
289
+ });
290
+ Object.defineProperty(exports, "fetchUpcomingEvents", {
291
+ enumerable: true,
292
+ get: function () { return chunk3MUOUXHV_js.fetchUpcomingEvents; }
293
+ });
294
+ Object.defineProperty(exports, "formatDate", {
295
+ enumerable: true,
296
+ get: function () { return chunk3MUOUXHV_js.formatDate; }
297
+ });
298
+ Object.defineProperty(exports, "formatDateTime", {
299
+ enumerable: true,
300
+ get: function () { return chunk3MUOUXHV_js.formatDateTime; }
301
+ });
302
+ Object.defineProperty(exports, "formatPrice", {
303
+ enumerable: true,
304
+ get: function () { return chunk3MUOUXHV_js.formatPrice; }
305
+ });
306
+ Object.defineProperty(exports, "getOfferingUrl", {
307
+ enumerable: true,
308
+ get: function () { return chunk3MUOUXHV_js.getOfferingUrl; }
309
+ });
310
+ Object.defineProperty(exports, "registerForEvent", {
311
+ enumerable: true,
312
+ get: function () { return chunk3MUOUXHV_js.registerForEvent; }
313
+ });
314
+ Object.defineProperty(exports, "useEventModal", {
315
+ enumerable: true,
316
+ get: function () { return chunk3MUOUXHV_js.useEventModal; }
317
+ });
318
+ exports.AffiliateCard = AffiliateCard;
319
+ exports.AffiliatesWidget = AffiliatesWidget;
320
+ exports.SiteKitProvider = SiteKitProvider;
321
+ exports.fetchAffiliates = fetchAffiliates;
322
+ exports.getTrackingUrl = getTrackingUrl;
323
+ exports.useAffiliates = useAffiliates;
324
+ exports.useSiteKit = useSiteKit;
325
+ //# sourceMappingURL=index.js.map
326
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/SiteKitProvider.tsx"],"names":["createContext","useContext","useEffect","configureFormsApi","useMemo","jsx","Suspense","AnalyticsProvider","jsxs","Fragment","EngageWidget"],"mappings":";;;;;;;;;;AAqBA,IAAM,cAAA,GAAiBA,oBAA0C,IAAI,CAAA;AAE9D,SAAS,UAAA,GAAkC;AAChD,EAAA,MAAM,OAAA,GAAUC,iBAAW,cAAc,CAAA;AACzC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,MAAA,GAAS,8BAAA;AAAA,EACT,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA,GAAQ;AACV,CAAA,EAAyB;AAEvB,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAChC,MAAC,OAAe,oBAAA,GAAuB,MAAA;AACvC,MAAC,OAAe,oBAAA,GAAuB,MAAA;AACvC,MAAC,OAAe,kBAAA,GAAqB,KAAA;AAAA,IACxC;AAGA,IAAAC,kCAAA,CAAkB;AAAA,MAChB,OAAA,EAAS,MAAA;AAAA,MACT;AAAA,KACD,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,KAAK,CAAC,CAAA;AAE1B,EAAA,MAAM,YAAA,GAAeC,aAAA;AAAA,IACnB,OAAO;AAAA,MACL,MAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA,EAAS;AAAA,KACX,CAAA;AAAA,IACA,CAAC,MAAA,EAAQ,MAAA,EAAQ,SAAA,EAAW,MAAA,EAAQ,OAAO,KAAK;AAAA,GAClD;AAGA,EAAA,IAAI,OAAA,yDAAa,QAAA,EAAS,CAAA;AAG1B,EAAA,IAAI,WAAW,OAAA,EAAS;AACtB,IAAA,OAAA,mBACEC,cAAA,CAACC,cAAA,EAAA,EAAS,QAAA,EAAU,IAAA,EAClB,QAAA,kBAAAD,cAAA;AAAA,MAACE,kCAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,MAAA;AAAA,QACA,cAAA,EAAgB,UAAU,cAAA,KAAmB,KAAA;AAAA,QAC7C,cAAA,EAAgB,UAAU,cAAA,KAAmB,KAAA;AAAA,QAC7C,KAAA;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,OAAA,mBACEC,eAAA,CAAAC,mBAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,sBACDJ,cAAA,CAACK,6BAAA,EAAA,EAAa,MAAA,EAAgB,MAAA,EAAgB;AAAA,KAAA,EAChD,CAAA;AAAA,EAEJ;AAEA,EAAA,sCACG,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAO,cAC7B,QAAA,EAAA,OAAA,EACH,CAAA;AAEJ","file":"index.js","sourcesContent":["/**\n * @uptrade/site-kit - SiteKitProvider\n * \n * Unified provider component that initializes all enabled modules.\n * All API calls go through Portal API with API key auth - never Supabase directly.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo, useEffect, ReactNode, Suspense } from 'react'\nimport type { SiteKitConfig } from './types'\n\n// Module providers\nimport { AnalyticsProvider } from './analytics/AnalyticsProvider'\nimport { EngageWidget } from './engage/EngageWidget'\nimport { configureFormsApi } from './forms/formsApi'\n\ninterface SiteKitContextValue extends SiteKitConfig {\n isReady: boolean\n}\n\nconst SiteKitContext = createContext<SiteKitContextValue | null>(null)\n\nexport function useSiteKit(): SiteKitContextValue {\n const context = useContext(SiteKitContext)\n if (!context) {\n throw new Error('useSiteKit must be used within a SiteKitProvider')\n }\n return context\n}\n\ninterface SiteKitProviderProps extends SiteKitConfig {\n children: ReactNode\n}\n\nexport function SiteKitProvider({\n children,\n apiUrl = 'https://api.uptrademedia.com',\n apiKey,\n analytics,\n engage,\n forms,\n debug = false,\n}: SiteKitProviderProps) {\n // Set window globals for Portal API access\n useEffect(() => {\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n \n // Configure forms API\n configureFormsApi({\n baseUrl: apiUrl,\n apiKey,\n })\n }, [apiUrl, apiKey, debug])\n\n const contextValue = useMemo<SiteKitContextValue>(\n () => ({\n apiUrl,\n apiKey,\n analytics,\n engage,\n forms,\n debug,\n isReady: true,\n }),\n [apiUrl, apiKey, analytics, engage, forms, debug]\n )\n\n // Build the provider tree based on enabled modules\n let content = <>{children}</>\n\n // Wrap with Analytics if enabled\n if (analytics?.enabled) {\n content = (\n <Suspense fallback={null}>\n <AnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n trackPageViews={analytics.trackPageViews !== false}\n trackWebVitals={analytics.trackWebVitals !== false}\n debug={debug}\n >\n {content}\n </AnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (doesn't wrap, just renders alongside)\n if (engage?.enabled) {\n content = (\n <>\n {content}\n <EngageWidget apiUrl={apiUrl} apiKey={apiKey} />\n </>\n )\n }\n\n return (\n <SiteKitContext.Provider value={contextValue}>\n {content}\n </SiteKitContext.Provider>\n )\n}\n\n/**\n * Hook to check if a specific module is enabled\n */\nexport function useModuleEnabled(module: 'analytics' | 'engage' | 'forms' | 'seo'): boolean {\n const context = useSiteKit()\n \n switch (module) {\n case 'analytics':\n return context.analytics?.enabled ?? false\n case 'engage':\n return context.engage?.enabled ?? false\n case 'forms':\n return context.forms?.enabled ?? false\n case 'seo':\n return true // SEO is always enabled via RSC components\n default:\n return false\n }\n}\n"]}