humanbehavior-js 0.5.69 → 0.5.70

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.
@@ -335,6 +335,57 @@ class AutoInstallationWizard {
335
335
  modifications.push(this.createEnvironmentModification(this.framework));
336
336
  return modifications;
337
337
  }
338
+ /**
339
+ * Helper: Merge HBProvider into existing providers.tsx file
340
+ */
341
+ mergeProvidersFile(filePath) {
342
+ const hbProviderContent = `export function HBProvider({ children }: { children: React.ReactNode }) {
343
+ return (
344
+ <HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
345
+ {children}
346
+ </HumanBehaviorProvider>
347
+ );
348
+ }`;
349
+ if (!fs.existsSync(filePath)) {
350
+ // File doesn't exist, create new file
351
+ return `'use client';
352
+
353
+ import { HumanBehaviorProvider } from 'humanbehavior-js/react';
354
+
355
+ ${hbProviderContent}`;
356
+ }
357
+ // File exists, read and merge
358
+ const existingContent = fs.readFileSync(filePath, 'utf8');
359
+ // Check if HBProvider already exists
360
+ if (existingContent.includes('export function HBProvider') || existingContent.includes('export const HBProvider')) {
361
+ // Already exists, return unchanged
362
+ return existingContent;
363
+ }
364
+ // Check if HumanBehaviorProvider import exists
365
+ let modifiedContent = existingContent;
366
+ if (!existingContent.includes("from 'humanbehavior-js/react'")) {
367
+ // Add the import - try to add after 'use client' or at the top
368
+ if (existingContent.includes("'use client'")) {
369
+ modifiedContent = existingContent.replace(/('use client';?)\s*\n/, `$1\n\nimport { HumanBehaviorProvider } from 'humanbehavior-js/react';\n`);
370
+ }
371
+ else {
372
+ // Add at the top
373
+ modifiedContent = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';\n\n${existingContent}`;
374
+ }
375
+ }
376
+ // Add HBProvider export at the end
377
+ // Ensure there's proper spacing before adding the export
378
+ const trimmed = modifiedContent.trimEnd();
379
+ if (trimmed === '') {
380
+ // File is empty (after trimming trailing whitespace)
381
+ modifiedContent = hbProviderContent;
382
+ }
383
+ else {
384
+ // Add double newline for separation
385
+ modifiedContent = `${trimmed}\n\n${hbProviderContent}`;
386
+ }
387
+ return modifiedContent;
388
+ }
338
389
  /**
339
390
  * Generate Next.js-specific modifications
340
391
  */
@@ -348,51 +399,48 @@ class AutoInstallationWizard {
348
399
  // Determine which layout file exists and set paths accordingly
349
400
  let actualAppLayoutFile = null;
350
401
  let providersFilePath = null;
402
+ let providersImportPath = null;
351
403
  if (fs.existsSync(appLayoutFileWithSrc)) {
352
404
  actualAppLayoutFile = appLayoutFileWithSrc;
353
405
  providersFilePath = path.join(this.projectRoot, 'src', 'app', 'providers.tsx');
406
+ providersImportPath = '@/app/providers';
354
407
  }
355
408
  else if (fs.existsSync(appLayoutFile)) {
356
409
  actualAppLayoutFile = appLayoutFile;
357
410
  providersFilePath = path.join(this.projectRoot, 'app', 'providers.tsx');
411
+ providersImportPath = '@/app/providers';
358
412
  }
359
413
  if (actualAppLayoutFile) {
360
- // Create providers.tsx file for App Router
414
+ // Merge or create providers.tsx file
415
+ const providersContent = this.mergeProvidersFile(providersFilePath);
416
+ const fileExists = fs.existsSync(providersFilePath);
361
417
  modifications.push({
362
418
  filePath: providersFilePath,
363
- action: 'create',
364
- content: `'use client';
365
-
366
- import { HumanBehaviorProvider } from 'humanbehavior-js/react';
367
-
368
- export function Providers({ children }: { children: React.ReactNode }) {
369
- return (
370
- <HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
371
- {children}
372
- </HumanBehaviorProvider>
373
- );
374
- }`,
375
- description: 'Created providers.tsx file for Next.js App Router'
419
+ action: fileExists ? 'modify' : 'create',
420
+ content: providersContent,
421
+ description: fileExists
422
+ ? 'Merged HBProvider into existing providers.tsx file'
423
+ : 'Created providers.tsx file with HBProvider for Next.js App Router'
376
424
  });
377
425
  // Modify layout.tsx to use the provider
378
426
  const content = fs.readFileSync(actualAppLayoutFile, 'utf8');
379
- const modifiedContent = this.injectNextJSAppRouter(content);
427
+ const modifiedContent = this.injectNextJSAppRouter(content, providersImportPath);
380
428
  modifications.push({
381
429
  filePath: actualAppLayoutFile,
382
430
  action: 'modify',
383
431
  content: modifiedContent,
384
- description: 'Added Providers wrapper to Next.js App Router layout'
432
+ description: 'Added HumanBehavior provider wrapper to Next.js App Router layout'
385
433
  });
386
434
  }
387
435
  else if (fs.existsSync(pagesLayoutFileWithSrc) || fs.existsSync(pagesLayoutFile)) {
388
436
  const actualPagesLayoutFile = fs.existsSync(pagesLayoutFileWithSrc) ? pagesLayoutFileWithSrc : pagesLayoutFile;
389
437
  const providersPath = fs.existsSync(pagesLayoutFileWithSrc)
390
- ? path.join(this.projectRoot, 'src', 'components', 'providers.tsx')
391
- : path.join(this.projectRoot, 'components', 'providers.tsx');
438
+ ? path.join(this.projectRoot, 'src', 'components', 'HumanBehaviorProvider.tsx')
439
+ : path.join(this.projectRoot, 'components', 'HumanBehaviorProvider.tsx');
392
440
  const importPath = fs.existsSync(pagesLayoutFileWithSrc)
393
- ? '../components/providers'
394
- : './components/providers';
395
- // Create providers.tsx file for Pages Router
441
+ ? '../components/HumanBehaviorProvider'
442
+ : './components/HumanBehaviorProvider';
443
+ // Create dedicated HumanBehavior provider file for Pages Router
396
444
  modifications.push({
397
445
  filePath: providersPath,
398
446
  action: 'create',
@@ -400,14 +448,14 @@ export function Providers({ children }: { children: React.ReactNode }) {
400
448
 
401
449
  import { HumanBehaviorProvider } from 'humanbehavior-js/react';
402
450
 
403
- export function Providers({ children }: { children: React.ReactNode }) {
451
+ export function HBProvider({ children }: { children: React.ReactNode }) {
404
452
  return (
405
453
  <HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
406
454
  {children}
407
455
  </HumanBehaviorProvider>
408
456
  );
409
457
  }`,
410
- description: 'Created providers.tsx file for Pages Router'
458
+ description: 'Created HumanBehavior provider file for Pages Router'
411
459
  });
412
460
  // Modify _app.tsx to use the provider
413
461
  const content = fs.readFileSync(actualPagesLayoutFile, 'utf8');
@@ -416,7 +464,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
416
464
  filePath: actualPagesLayoutFile,
417
465
  action: 'modify',
418
466
  content: modifiedContent,
419
- description: 'Added Providers wrapper to Next.js Pages Router'
467
+ description: 'Added HumanBehavior provider wrapper to Next.js Pages Router'
420
468
  });
421
469
  }
422
470
  // Create or append to environment file
@@ -978,11 +1026,11 @@ export const onClientEntry = () => {
978
1026
  // Fallback: simple injection
979
1027
  return `${importStatement}\n\n${content}`;
980
1028
  }
981
- injectNextJSAppRouter(content) {
982
- if (content.includes('Providers')) {
1029
+ injectNextJSAppRouter(content, importPath = '@/app/providers') {
1030
+ if (content.includes('HBProvider')) {
983
1031
  return content;
984
1032
  }
985
- const importStatement = `import { Providers } from './providers';`;
1033
+ const importStatement = `import { HBProvider } from '${importPath}';`;
986
1034
  // First, add the import statement
987
1035
  let modifiedContent = content.replace(/export default function RootLayout/, `${importStatement}\n\nexport default function RootLayout`);
988
1036
  // Then wrap the body content with Providers
@@ -991,22 +1039,22 @@ export const onClientEntry = () => {
991
1039
  // Trim whitespace and newlines from bodyContent
992
1040
  const trimmedContent = bodyContent.trim();
993
1041
  return `<body${bodyAttrs}>
994
- <Providers>
1042
+ <HBProvider>
995
1043
  ${trimmedContent}
996
- </Providers>
1044
+ </HBProvider>
997
1045
  </body>`;
998
1046
  });
999
1047
  return modifiedContent;
1000
1048
  }
1001
- injectNextJSPagesRouter(content, importPath = '../components/providers') {
1002
- if (content.includes('Providers')) {
1049
+ injectNextJSPagesRouter(content, importPath = '../components/HumanBehaviorProvider') {
1050
+ if (content.includes('HBProvider')) {
1003
1051
  return content;
1004
1052
  }
1005
- const importStatement = `import { Providers } from '${importPath}';`;
1053
+ const importStatement = `import { HBProvider } from '${importPath}';`;
1006
1054
  return content.replace(/function MyApp/, `${importStatement}\n\nfunction MyApp`).replace(/return \(([\s\S]*?)\);/, `return (
1007
- <Providers>
1055
+ <HBProvider>
1008
1056
  $1
1009
- </Providers>
1057
+ </HBProvider>
1010
1058
  );`);
1011
1059
  }
1012
1060
  injectRemixProvider(content) {