humanbehavior-js 0.4.13 → 0.4.15
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.
- package/dist/cjs/install-wizard.cjs +396 -25
- package/dist/cjs/install-wizard.cjs.map +1 -1
- package/dist/cjs/wizard/index.cjs +633 -395
- package/dist/cjs/wizard/index.cjs.map +1 -1
- package/dist/cli/ai-auto-install.cjs +57161 -0
- package/dist/cli/ai-auto-install.cjs.map +1 -0
- package/dist/cli/ai-auto-install.js +520 -575
- package/dist/cli/ai-auto-install.js.map +1 -1
- package/dist/cli/auto-install.cjs +56352 -0
- package/dist/cli/auto-install.cjs.map +1 -0
- package/dist/cli/auto-install.js +925 -140
- package/dist/cli/auto-install.js.map +1 -1
- package/dist/esm/install-wizard.js +396 -25
- package/dist/esm/install-wizard.js.map +1 -1
- package/dist/esm/wizard/index.js +631 -394
- package/dist/esm/wizard/index.js.map +1 -1
- package/dist/types/install-wizard.d.ts +31 -1
- package/dist/types/wizard/index.d.ts +44 -10
- package/package.json +3 -1
- package/rollup.config.js +5 -1
- package/src/types/clack.d.ts +31 -0
- package/src/wizard/ai/ai-install-wizard.ts +4 -1
- package/src/wizard/ai/manual-framework-wizard.ts +2 -0
- package/src/wizard/cli/ai-auto-install.ts +122 -248
- package/src/wizard/cli/auto-install.ts +116 -117
- package/src/wizard/core/install-wizard.ts +498 -60
- package/src/wizard/services/centralized-ai-service.ts +1 -1
- package/src/wizard/services/remote-ai-service.ts +18 -2
- package/tsconfig.json +1 -1
|
@@ -67,6 +67,28 @@ class AutoInstallationWizard {
|
|
|
67
67
|
this.apiKey = apiKey;
|
|
68
68
|
this.projectRoot = projectRoot;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Simple version comparison utility
|
|
72
|
+
*/
|
|
73
|
+
compareVersions(version1, version2) {
|
|
74
|
+
const v1Parts = version1.split('.').map(Number);
|
|
75
|
+
const v2Parts = version2.split('.').map(Number);
|
|
76
|
+
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
|
77
|
+
const v1 = v1Parts[i] || 0;
|
|
78
|
+
const v2 = v2Parts[i] || 0;
|
|
79
|
+
if (v1 > v2)
|
|
80
|
+
return 1;
|
|
81
|
+
if (v1 < v2)
|
|
82
|
+
return -1;
|
|
83
|
+
}
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
isVersionGte(version, target) {
|
|
87
|
+
return this.compareVersions(version, target) >= 0;
|
|
88
|
+
}
|
|
89
|
+
getMajorVersion(version) {
|
|
90
|
+
return parseInt(version.split('.')[0]) || 0;
|
|
91
|
+
}
|
|
70
92
|
/**
|
|
71
93
|
* Main installation method - detects framework and auto-installs
|
|
72
94
|
*/
|
|
@@ -116,73 +138,146 @@ class AutoInstallationWizard {
|
|
|
116
138
|
}
|
|
117
139
|
const packageJson = JSON.parse(fs__namespace.readFileSync(packageJsonPath, 'utf8'));
|
|
118
140
|
const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
|
|
119
|
-
// Detect framework
|
|
141
|
+
// Detect framework with version information
|
|
120
142
|
let framework = {
|
|
121
143
|
name: 'vanilla',
|
|
122
144
|
type: 'vanilla',
|
|
123
|
-
projectRoot: this.projectRoot
|
|
145
|
+
projectRoot: this.projectRoot,
|
|
146
|
+
features: {}
|
|
124
147
|
};
|
|
125
148
|
if (dependencies.nuxt) {
|
|
149
|
+
const nuxtVersion = dependencies.nuxt;
|
|
150
|
+
const isNuxt3 = this.isVersionGte(nuxtVersion, '3.0.0');
|
|
126
151
|
framework = {
|
|
127
152
|
name: 'nuxt',
|
|
128
153
|
type: 'nuxt',
|
|
154
|
+
version: nuxtVersion,
|
|
155
|
+
majorVersion: this.getMajorVersion(nuxtVersion),
|
|
129
156
|
hasTypeScript: !!dependencies.typescript,
|
|
130
157
|
hasRouter: true,
|
|
131
|
-
projectRoot: this.projectRoot
|
|
158
|
+
projectRoot: this.projectRoot,
|
|
159
|
+
features: {
|
|
160
|
+
hasNuxt3: isNuxt3
|
|
161
|
+
}
|
|
132
162
|
};
|
|
133
163
|
}
|
|
134
164
|
else if (dependencies.next) {
|
|
165
|
+
const nextVersion = dependencies.next;
|
|
166
|
+
const isNext13 = this.isVersionGte(nextVersion, '13.0.0');
|
|
135
167
|
framework = {
|
|
136
168
|
name: 'nextjs',
|
|
137
169
|
type: 'nextjs',
|
|
170
|
+
version: nextVersion,
|
|
171
|
+
majorVersion: this.getMajorVersion(nextVersion),
|
|
138
172
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/node'],
|
|
139
173
|
hasRouter: true,
|
|
140
|
-
projectRoot: this.projectRoot
|
|
174
|
+
projectRoot: this.projectRoot,
|
|
175
|
+
features: {
|
|
176
|
+
hasNextAppRouter: isNext13
|
|
177
|
+
}
|
|
141
178
|
};
|
|
142
179
|
}
|
|
143
180
|
else if (dependencies['@remix-run/react'] || dependencies['@remix-run/dev']) {
|
|
181
|
+
const remixVersion = dependencies['@remix-run/react'] || dependencies['@remix-run/dev'];
|
|
144
182
|
framework = {
|
|
145
183
|
name: 'remix',
|
|
146
184
|
type: 'remix',
|
|
185
|
+
version: remixVersion,
|
|
186
|
+
majorVersion: this.getMajorVersion(remixVersion),
|
|
147
187
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
148
188
|
hasRouter: true,
|
|
149
|
-
projectRoot: this.projectRoot
|
|
189
|
+
projectRoot: this.projectRoot,
|
|
190
|
+
features: {}
|
|
150
191
|
};
|
|
151
192
|
}
|
|
152
193
|
else if (dependencies.react) {
|
|
194
|
+
const reactVersion = dependencies.react;
|
|
195
|
+
const isReact18 = this.isVersionGte(reactVersion, '18.0.0');
|
|
153
196
|
framework = {
|
|
154
197
|
name: 'react',
|
|
155
198
|
type: 'react',
|
|
199
|
+
version: reactVersion,
|
|
200
|
+
majorVersion: this.getMajorVersion(reactVersion),
|
|
156
201
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
157
202
|
hasRouter: !!dependencies['react-router-dom'] || !!dependencies['react-router'],
|
|
158
|
-
projectRoot: this.projectRoot
|
|
203
|
+
projectRoot: this.projectRoot,
|
|
204
|
+
features: {
|
|
205
|
+
hasReact18: isReact18
|
|
206
|
+
}
|
|
159
207
|
};
|
|
160
208
|
}
|
|
161
209
|
else if (dependencies.vue) {
|
|
210
|
+
const vueVersion = dependencies.vue;
|
|
211
|
+
const isVue3 = this.isVersionGte(vueVersion, '3.0.0');
|
|
162
212
|
framework = {
|
|
163
213
|
name: 'vue',
|
|
164
214
|
type: 'vue',
|
|
215
|
+
version: vueVersion,
|
|
216
|
+
majorVersion: this.getMajorVersion(vueVersion),
|
|
165
217
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@vue/cli-service'],
|
|
166
218
|
hasRouter: !!dependencies['vue-router'],
|
|
167
|
-
projectRoot: this.projectRoot
|
|
219
|
+
projectRoot: this.projectRoot,
|
|
220
|
+
features: {
|
|
221
|
+
hasVue3: isVue3
|
|
222
|
+
}
|
|
168
223
|
};
|
|
169
224
|
}
|
|
170
225
|
else if (dependencies['@angular/core']) {
|
|
226
|
+
const angularVersion = dependencies['@angular/core'];
|
|
227
|
+
const isAngular17 = this.isVersionGte(angularVersion, '17.0.0');
|
|
171
228
|
framework = {
|
|
172
229
|
name: 'angular',
|
|
173
230
|
type: 'angular',
|
|
231
|
+
version: angularVersion,
|
|
232
|
+
majorVersion: this.getMajorVersion(angularVersion),
|
|
174
233
|
hasTypeScript: true,
|
|
175
234
|
hasRouter: true,
|
|
176
|
-
projectRoot: this.projectRoot
|
|
235
|
+
projectRoot: this.projectRoot,
|
|
236
|
+
features: {
|
|
237
|
+
hasAngularStandalone: isAngular17
|
|
238
|
+
}
|
|
177
239
|
};
|
|
178
240
|
}
|
|
179
241
|
else if (dependencies.svelte) {
|
|
242
|
+
const svelteVersion = dependencies.svelte;
|
|
243
|
+
const isSvelteKit = !!dependencies['@sveltejs/kit'];
|
|
180
244
|
framework = {
|
|
181
245
|
name: 'svelte',
|
|
182
246
|
type: 'svelte',
|
|
247
|
+
version: svelteVersion,
|
|
248
|
+
majorVersion: this.getMajorVersion(svelteVersion),
|
|
183
249
|
hasTypeScript: !!dependencies.typescript || !!dependencies['svelte-check'],
|
|
184
250
|
hasRouter: !!dependencies['svelte-routing'] || !!dependencies['@sveltejs/kit'],
|
|
185
|
-
projectRoot: this.projectRoot
|
|
251
|
+
projectRoot: this.projectRoot,
|
|
252
|
+
features: {
|
|
253
|
+
hasSvelteKit: isSvelteKit
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
else if (dependencies.astro) {
|
|
258
|
+
const astroVersion = dependencies.astro;
|
|
259
|
+
framework = {
|
|
260
|
+
name: 'astro',
|
|
261
|
+
type: 'astro',
|
|
262
|
+
version: astroVersion,
|
|
263
|
+
majorVersion: this.getMajorVersion(astroVersion),
|
|
264
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@astrojs/ts-plugin'],
|
|
265
|
+
hasRouter: true,
|
|
266
|
+
projectRoot: this.projectRoot,
|
|
267
|
+
features: {}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
else if (dependencies.gatsby) {
|
|
271
|
+
const gatsbyVersion = dependencies.gatsby;
|
|
272
|
+
framework = {
|
|
273
|
+
name: 'gatsby',
|
|
274
|
+
type: 'gatsby',
|
|
275
|
+
version: gatsbyVersion,
|
|
276
|
+
majorVersion: this.getMajorVersion(gatsbyVersion),
|
|
277
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
278
|
+
hasRouter: true,
|
|
279
|
+
projectRoot: this.projectRoot,
|
|
280
|
+
features: {}
|
|
186
281
|
};
|
|
187
282
|
}
|
|
188
283
|
// Detect bundler
|
|
@@ -216,13 +311,18 @@ class AutoInstallationWizard {
|
|
|
216
311
|
*/
|
|
217
312
|
installPackage() {
|
|
218
313
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
var _a, _b;
|
|
314
|
+
var _a, _b, _c, _d;
|
|
220
315
|
const { execSync } = yield import('child_process');
|
|
221
|
-
|
|
316
|
+
// Build base command
|
|
317
|
+
let command = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.packageManager) === 'yarn'
|
|
222
318
|
? 'yarn add humanbehavior-js'
|
|
223
319
|
: ((_b = this.framework) === null || _b === void 0 ? void 0 : _b.packageManager) === 'pnpm'
|
|
224
320
|
? 'pnpm add humanbehavior-js'
|
|
225
321
|
: 'npm install humanbehavior-js';
|
|
322
|
+
// Add legacy peer deps flag for npm to handle dependency conflicts
|
|
323
|
+
if (((_c = this.framework) === null || _c === void 0 ? void 0 : _c.packageManager) !== 'yarn' && ((_d = this.framework) === null || _d === void 0 ? void 0 : _d.packageManager) !== 'pnpm') {
|
|
324
|
+
command += ' --legacy-peer-deps';
|
|
325
|
+
}
|
|
226
326
|
try {
|
|
227
327
|
execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
|
|
228
328
|
}
|
|
@@ -248,6 +348,12 @@ class AutoInstallationWizard {
|
|
|
248
348
|
case 'nuxt':
|
|
249
349
|
modifications.push(...yield this.generateNuxtModifications());
|
|
250
350
|
break;
|
|
351
|
+
case 'astro':
|
|
352
|
+
modifications.push(...yield this.generateAstroModifications());
|
|
353
|
+
break;
|
|
354
|
+
case 'gatsby':
|
|
355
|
+
modifications.push(...yield this.generateGatsbyModifications());
|
|
356
|
+
break;
|
|
251
357
|
case 'remix':
|
|
252
358
|
modifications.push(...yield this.generateRemixModifications());
|
|
253
359
|
break;
|
|
@@ -359,6 +465,84 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
359
465
|
return modifications;
|
|
360
466
|
});
|
|
361
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Generate Astro-specific modifications
|
|
470
|
+
*/
|
|
471
|
+
generateAstroModifications() {
|
|
472
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
473
|
+
const modifications = [];
|
|
474
|
+
// Create Astro component for HumanBehavior
|
|
475
|
+
const astroComponentPath = path__namespace.join(this.projectRoot, 'src', 'components', 'HumanBehavior.astro');
|
|
476
|
+
const astroComponentContent = `---
|
|
477
|
+
// This component will only run on the client side
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
<script>
|
|
481
|
+
import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
482
|
+
|
|
483
|
+
// Get API key from environment variable
|
|
484
|
+
const apiKey = import.meta.env.PUBLIC_HUMANBEHAVIOR_API_KEY;
|
|
485
|
+
|
|
486
|
+
console.log('HumanBehavior: API key found:', apiKey ? 'Yes' : 'No');
|
|
487
|
+
|
|
488
|
+
if (apiKey) {
|
|
489
|
+
try {
|
|
490
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
491
|
+
console.log('HumanBehavior: Tracker initialized successfully');
|
|
492
|
+
|
|
493
|
+
// Test event to verify tracking is working
|
|
494
|
+
setTimeout(() => {
|
|
495
|
+
tracker.customEvent('astro_page_view', {
|
|
496
|
+
page: window.location.pathname,
|
|
497
|
+
framework: 'astro'
|
|
498
|
+
}).then(() => {
|
|
499
|
+
console.log('HumanBehavior: Test event sent successfully');
|
|
500
|
+
}).catch((error) => {
|
|
501
|
+
console.error('HumanBehavior: Failed to send test event:', error);
|
|
502
|
+
});
|
|
503
|
+
}, 1000);
|
|
504
|
+
|
|
505
|
+
} catch (error) {
|
|
506
|
+
console.error('HumanBehavior: Failed to initialize tracker:', error);
|
|
507
|
+
}
|
|
508
|
+
} else {
|
|
509
|
+
console.error('HumanBehavior: No API key found');
|
|
510
|
+
}
|
|
511
|
+
</script>`;
|
|
512
|
+
modifications.push({
|
|
513
|
+
filePath: astroComponentPath,
|
|
514
|
+
action: 'create',
|
|
515
|
+
content: astroComponentContent,
|
|
516
|
+
description: 'Created Astro component for HumanBehavior SDK'
|
|
517
|
+
});
|
|
518
|
+
// Find and update layout file
|
|
519
|
+
const layoutFiles = [
|
|
520
|
+
path__namespace.join(this.projectRoot, 'src', 'layouts', 'Layout.astro'),
|
|
521
|
+
path__namespace.join(this.projectRoot, 'src', 'layouts', 'layout.astro'),
|
|
522
|
+
path__namespace.join(this.projectRoot, 'src', 'layouts', 'BaseLayout.astro')
|
|
523
|
+
];
|
|
524
|
+
let layoutFile = null;
|
|
525
|
+
for (const file of layoutFiles) {
|
|
526
|
+
if (fs__namespace.existsSync(file)) {
|
|
527
|
+
layoutFile = file;
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (layoutFile) {
|
|
532
|
+
const content = fs__namespace.readFileSync(layoutFile, 'utf8');
|
|
533
|
+
const modifiedContent = this.injectAstroLayout(content);
|
|
534
|
+
modifications.push({
|
|
535
|
+
filePath: layoutFile,
|
|
536
|
+
action: 'modify',
|
|
537
|
+
content: modifiedContent,
|
|
538
|
+
description: 'Added HumanBehavior component to Astro layout'
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
// Add environment variable
|
|
542
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
543
|
+
return modifications;
|
|
544
|
+
});
|
|
545
|
+
}
|
|
362
546
|
/**
|
|
363
547
|
* Generate Nuxt-specific modifications
|
|
364
548
|
*/
|
|
@@ -579,6 +763,50 @@ export default defineNuxtPlugin(() => {
|
|
|
579
763
|
return modifications;
|
|
580
764
|
});
|
|
581
765
|
}
|
|
766
|
+
/**
|
|
767
|
+
* Generate Gatsby-specific modifications
|
|
768
|
+
*/
|
|
769
|
+
generateGatsbyModifications() {
|
|
770
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
771
|
+
const modifications = [];
|
|
772
|
+
// Modify or create gatsby-browser.js for Gatsby
|
|
773
|
+
const gatsbyBrowserFile = path__namespace.join(this.projectRoot, 'gatsby-browser.js');
|
|
774
|
+
if (fs__namespace.existsSync(gatsbyBrowserFile)) {
|
|
775
|
+
const content = fs__namespace.readFileSync(gatsbyBrowserFile, 'utf8');
|
|
776
|
+
const modifiedContent = this.injectGatsbyBrowser(content);
|
|
777
|
+
modifications.push({
|
|
778
|
+
filePath: gatsbyBrowserFile,
|
|
779
|
+
action: 'modify',
|
|
780
|
+
content: modifiedContent,
|
|
781
|
+
description: 'Added HumanBehavior initialization to Gatsby browser'
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
// Create gatsby-browser.js if it doesn't exist
|
|
786
|
+
modifications.push({
|
|
787
|
+
filePath: gatsbyBrowserFile,
|
|
788
|
+
action: 'create',
|
|
789
|
+
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
790
|
+
|
|
791
|
+
export const onClientEntry = () => {
|
|
792
|
+
console.log('Gatsby browser entry point loaded');
|
|
793
|
+
const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
|
|
794
|
+
console.log('API Key found:', apiKey ? 'Yes' : 'No');
|
|
795
|
+
if (apiKey) {
|
|
796
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
797
|
+
console.log('HumanBehavior SDK initialized for Gatsby');
|
|
798
|
+
} else {
|
|
799
|
+
console.log('No API key found in environment variables');
|
|
800
|
+
}
|
|
801
|
+
};`,
|
|
802
|
+
description: 'Created gatsby-browser.js with HumanBehavior initialization'
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
// Create or append to environment file
|
|
806
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
807
|
+
return modifications;
|
|
808
|
+
});
|
|
809
|
+
}
|
|
582
810
|
/**
|
|
583
811
|
* Apply modifications to the codebase
|
|
584
812
|
*/
|
|
@@ -673,7 +901,7 @@ export default defineNuxtPlugin(() => {
|
|
|
673
901
|
return null;
|
|
674
902
|
}
|
|
675
903
|
injectReactProvider(content, filePath) {
|
|
676
|
-
var _a;
|
|
904
|
+
var _a, _b, _c;
|
|
677
905
|
filePath.endsWith('.tsx') || filePath.endsWith('.ts');
|
|
678
906
|
// Check if already has HumanBehaviorProvider
|
|
679
907
|
if (content.includes('HumanBehaviorProvider')) {
|
|
@@ -685,14 +913,39 @@ export default defineNuxtPlugin(() => {
|
|
|
685
913
|
? 'import.meta.env.VITE_HUMANBEHAVIOR_API_KEY!'
|
|
686
914
|
: 'process.env.HUMANBEHAVIOR_API_KEY!';
|
|
687
915
|
const importStatement = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';`;
|
|
688
|
-
//
|
|
916
|
+
// Enhanced parsing for React 18+ features
|
|
917
|
+
const hasReact18 = (_c = (_b = this.framework) === null || _b === void 0 ? void 0 : _b.features) === null || _c === void 0 ? void 0 : _c.hasReact18;
|
|
918
|
+
// Handle different React patterns
|
|
689
919
|
if (content.includes('function App()') || content.includes('const App =')) {
|
|
690
|
-
|
|
920
|
+
// Add import statement
|
|
921
|
+
let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
|
|
922
|
+
// If no React import found, add it at the top
|
|
923
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
924
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
925
|
+
}
|
|
926
|
+
// Wrap the App component return with HumanBehaviorProvider
|
|
927
|
+
modifiedContent = modifiedContent.replace(/(return\s*\([\s\S]*?\)\s*;)/, `return (
|
|
691
928
|
<HumanBehaviorProvider apiKey={${envVar}}>
|
|
692
929
|
$1
|
|
693
930
|
</HumanBehaviorProvider>
|
|
694
931
|
);`);
|
|
932
|
+
return modifiedContent;
|
|
695
933
|
}
|
|
934
|
+
// Handle React 18+ createRoot pattern
|
|
935
|
+
if (hasReact18 && content.includes('createRoot')) {
|
|
936
|
+
let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
|
|
937
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
938
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
939
|
+
}
|
|
940
|
+
// Wrap the root render with HumanBehaviorProvider
|
|
941
|
+
modifiedContent = modifiedContent.replace(/(root\.render\s*\([\s\S]*?\)\s*;)/, `root.render(
|
|
942
|
+
<HumanBehaviorProvider apiKey={${envVar}}>
|
|
943
|
+
$1
|
|
944
|
+
</HumanBehaviorProvider>
|
|
945
|
+
);`);
|
|
946
|
+
return modifiedContent;
|
|
947
|
+
}
|
|
948
|
+
// Fallback: simple injection
|
|
696
949
|
return `${importStatement}\n\n${content}`;
|
|
697
950
|
}
|
|
698
951
|
injectNextJSAppRouter(content) {
|
|
@@ -789,21 +1042,51 @@ export default function App()`);
|
|
|
789
1042
|
return modifiedContent;
|
|
790
1043
|
}
|
|
791
1044
|
injectVuePlugin(content) {
|
|
1045
|
+
var _a, _b;
|
|
792
1046
|
if (content.includes('HumanBehaviorPlugin')) {
|
|
793
1047
|
return content;
|
|
794
1048
|
}
|
|
795
1049
|
const importStatement = `import { HumanBehaviorPlugin } from 'humanbehavior-js/vue';`;
|
|
796
|
-
|
|
1050
|
+
// Enhanced Vue 3 support with version detection
|
|
1051
|
+
const hasVue3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasVue3;
|
|
1052
|
+
if (hasVue3) {
|
|
1053
|
+
// Vue 3 with Composition API
|
|
1054
|
+
const pluginUsage = `app.use(HumanBehaviorPlugin, {
|
|
797
1055
|
apiKey: import.meta.env.VITE_HUMANBEHAVIOR_API_KEY
|
|
798
1056
|
});`;
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
1057
|
+
let modifiedContent = content;
|
|
1058
|
+
// Add import statement
|
|
1059
|
+
if (!content.includes(importStatement)) {
|
|
1060
|
+
modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
|
|
1061
|
+
// If no Vue import found, add it at the top
|
|
1062
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
1063
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
// Handle createApp pattern
|
|
1067
|
+
if (content.includes('createApp')) {
|
|
1068
|
+
modifiedContent = modifiedContent.replace(/(app\.mount\(.*?\))/, `${pluginUsage}\n\n$1`);
|
|
1069
|
+
}
|
|
1070
|
+
return modifiedContent;
|
|
803
1071
|
}
|
|
804
1072
|
else {
|
|
805
|
-
// Vue 2
|
|
806
|
-
|
|
1073
|
+
// Vue 2 with Options API
|
|
1074
|
+
const pluginUsage = `Vue.use(HumanBehaviorPlugin, {
|
|
1075
|
+
apiKey: process.env.VUE_APP_HUMANBEHAVIOR_API_KEY
|
|
1076
|
+
});`;
|
|
1077
|
+
let modifiedContent = content;
|
|
1078
|
+
// Add import statement
|
|
1079
|
+
if (!content.includes(importStatement)) {
|
|
1080
|
+
modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
|
|
1081
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
1082
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
// Handle new Vue pattern
|
|
1086
|
+
if (content.includes('new Vue')) {
|
|
1087
|
+
modifiedContent = modifiedContent.replace(/(new Vue\(.*?\))/, `${pluginUsage}\n\n$1`);
|
|
1088
|
+
}
|
|
1089
|
+
return modifiedContent;
|
|
807
1090
|
}
|
|
808
1091
|
}
|
|
809
1092
|
injectAngularModule(content) {
|
|
@@ -884,17 +1167,99 @@ if (typeof window !== 'undefined') {
|
|
|
884
1167
|
</script>`;
|
|
885
1168
|
return content.replace(/<\/head>/, ` ${cdnScript}\n ${initScript}\n</head>`);
|
|
886
1169
|
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Inject Astro layout with HumanBehavior component
|
|
1172
|
+
*/
|
|
1173
|
+
injectAstroLayout(content) {
|
|
1174
|
+
// Check if HumanBehavior component is already imported
|
|
1175
|
+
if (content.includes('HumanBehavior') || content.includes('humanbehavior-js')) {
|
|
1176
|
+
return content; // Already has HumanBehavior
|
|
1177
|
+
}
|
|
1178
|
+
// Add import inside frontmatter if not present
|
|
1179
|
+
let modifiedContent = content;
|
|
1180
|
+
if (!content.includes('import HumanBehavior')) {
|
|
1181
|
+
const importStatement = 'import HumanBehavior from \'../components/HumanBehavior.astro\';';
|
|
1182
|
+
const frontmatterEndIndex = content.indexOf('---', 3);
|
|
1183
|
+
if (frontmatterEndIndex !== -1) {
|
|
1184
|
+
// Insert import inside frontmatter, before the closing ---
|
|
1185
|
+
modifiedContent = content.slice(0, frontmatterEndIndex) + '\n' + importStatement + '\n' + content.slice(frontmatterEndIndex);
|
|
1186
|
+
}
|
|
1187
|
+
else {
|
|
1188
|
+
// No frontmatter, add at the very beginning
|
|
1189
|
+
modifiedContent = '---\n' + importStatement + '\n---\n\n' + content;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
// Find the closing </body> tag and add HumanBehavior component before it
|
|
1193
|
+
const bodyCloseIndex = modifiedContent.lastIndexOf('</body>');
|
|
1194
|
+
if (bodyCloseIndex === -1) {
|
|
1195
|
+
// No body tag found, append to end
|
|
1196
|
+
return modifiedContent + '\n\n<HumanBehavior />';
|
|
1197
|
+
}
|
|
1198
|
+
// Add component before closing body tag
|
|
1199
|
+
return modifiedContent.slice(0, bodyCloseIndex) + ' <HumanBehavior />\n' + modifiedContent.slice(bodyCloseIndex);
|
|
1200
|
+
}
|
|
887
1201
|
injectNuxtConfig(content) {
|
|
1202
|
+
var _a, _b;
|
|
888
1203
|
if (content.includes('humanBehaviorApiKey')) {
|
|
889
1204
|
return content;
|
|
890
1205
|
}
|
|
891
|
-
//
|
|
892
|
-
|
|
1206
|
+
// Enhanced Nuxt 3 support with version detection
|
|
1207
|
+
const hasNuxt3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasNuxt3;
|
|
1208
|
+
if (hasNuxt3) {
|
|
1209
|
+
// Nuxt 3 with runtime config
|
|
1210
|
+
return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
|
|
893
1211
|
runtimeConfig: {
|
|
894
1212
|
public: {
|
|
895
1213
|
humanBehaviorApiKey: process.env.NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY
|
|
896
1214
|
}
|
|
897
1215
|
},`);
|
|
1216
|
+
}
|
|
1217
|
+
else {
|
|
1218
|
+
// Nuxt 2 with env config
|
|
1219
|
+
return content.replace(/export default \{/, `export default {
|
|
1220
|
+
env: {
|
|
1221
|
+
humanBehaviorApiKey: process.env.HUMANBEHAVIOR_API_KEY
|
|
1222
|
+
},`);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
injectGatsbyLayout(content) {
|
|
1226
|
+
if (content.includes('HumanBehavior')) {
|
|
1227
|
+
return content;
|
|
1228
|
+
}
|
|
1229
|
+
const importStatement = `import HumanBehavior from './HumanBehavior';`;
|
|
1230
|
+
const componentUsage = `<HumanBehavior apiKey={process.env.GATSBY_HUMANBEHAVIOR_API_KEY || ''} />`;
|
|
1231
|
+
// Add import at the top
|
|
1232
|
+
let modifiedContent = content.replace(/import.*from.*['"]\./, `${importStatement}\n$&`);
|
|
1233
|
+
// Add component before closing body tag
|
|
1234
|
+
modifiedContent = modifiedContent.replace(/(\s*<\/body>)/, `\n ${componentUsage}\n$1`);
|
|
1235
|
+
return modifiedContent;
|
|
1236
|
+
}
|
|
1237
|
+
injectGatsbyBrowser(content) {
|
|
1238
|
+
if (content.includes('HumanBehaviorTracker')) {
|
|
1239
|
+
return content;
|
|
1240
|
+
}
|
|
1241
|
+
const importStatement = `import { HumanBehaviorTracker } from 'humanbehavior-js';`;
|
|
1242
|
+
const initCode = `
|
|
1243
|
+
// Initialize HumanBehavior SDK
|
|
1244
|
+
export const onClientEntry = () => {
|
|
1245
|
+
console.log('Gatsby browser entry point loaded');
|
|
1246
|
+
const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
|
|
1247
|
+
console.log('API Key found:', apiKey ? 'Yes' : 'No');
|
|
1248
|
+
if (apiKey) {
|
|
1249
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
1250
|
+
console.log('HumanBehavior SDK initialized for Gatsby');
|
|
1251
|
+
} else {
|
|
1252
|
+
console.log('No API key found in environment variables');
|
|
1253
|
+
}
|
|
1254
|
+
};`;
|
|
1255
|
+
// If the file already has content, add the import and init code
|
|
1256
|
+
if (content.trim()) {
|
|
1257
|
+
return `${importStatement}${initCode}\n\n${content}`;
|
|
1258
|
+
}
|
|
1259
|
+
else {
|
|
1260
|
+
// If file is empty, just return the new content
|
|
1261
|
+
return `${importStatement}${initCode}`;
|
|
1262
|
+
}
|
|
898
1263
|
}
|
|
899
1264
|
/**
|
|
900
1265
|
* Helper method to find the best environment file for a framework
|
|
@@ -925,6 +1290,8 @@ if (typeof window !== 'undefined') {
|
|
|
925
1290
|
nuxt: 'NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
926
1291
|
remix: 'HUMANBEHAVIOR_API_KEY',
|
|
927
1292
|
vanilla: 'HUMANBEHAVIOR_API_KEY',
|
|
1293
|
+
astro: 'PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
1294
|
+
gatsby: 'GATSBY_HUMANBEHAVIOR_API_KEY',
|
|
928
1295
|
node: 'HUMANBEHAVIOR_API_KEY',
|
|
929
1296
|
auto: 'HUMANBEHAVIOR_API_KEY'
|
|
930
1297
|
};
|
|
@@ -948,6 +1315,8 @@ if (typeof window !== 'undefined') {
|
|
|
948
1315
|
nuxt: '.env',
|
|
949
1316
|
remix: '.env.local',
|
|
950
1317
|
vanilla: '.env',
|
|
1318
|
+
astro: '.env',
|
|
1319
|
+
gatsby: '.env.development',
|
|
951
1320
|
node: '.env',
|
|
952
1321
|
auto: '.env'
|
|
953
1322
|
};
|
|
@@ -962,6 +1331,8 @@ if (typeof window !== 'undefined') {
|
|
|
962
1331
|
*/
|
|
963
1332
|
createEnvironmentModification(framework) {
|
|
964
1333
|
const { filePath, envVarName } = this.findBestEnvFile(framework);
|
|
1334
|
+
// Clean the API key to prevent formatting issues
|
|
1335
|
+
const cleanApiKey = this.apiKey.trim();
|
|
965
1336
|
if (fs__namespace.existsSync(filePath)) {
|
|
966
1337
|
// Check if the variable already exists
|
|
967
1338
|
const content = fs__namespace.readFileSync(filePath, 'utf8');
|
|
@@ -979,7 +1350,7 @@ if (typeof window !== 'undefined') {
|
|
|
979
1350
|
return {
|
|
980
1351
|
filePath,
|
|
981
1352
|
action: 'append',
|
|
982
|
-
content: `\n${envVarName}=${
|
|
1353
|
+
content: `\n${envVarName}=${cleanApiKey}`,
|
|
983
1354
|
description: `Added API key to existing ${path__namespace.basename(filePath)}`
|
|
984
1355
|
};
|
|
985
1356
|
}
|
|
@@ -989,7 +1360,7 @@ if (typeof window !== 'undefined') {
|
|
|
989
1360
|
return {
|
|
990
1361
|
filePath,
|
|
991
1362
|
action: 'create',
|
|
992
|
-
content: `${envVarName}=${
|
|
1363
|
+
content: `${envVarName}=${cleanApiKey}`,
|
|
993
1364
|
description: `Created ${path__namespace.basename(filePath)} with API key`
|
|
994
1365
|
};
|
|
995
1366
|
}
|