@mahe_pkm/buzl-capi 0.1.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,22 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
- ## [0.1.2] - 2026-09-14
11
-
12
- ### Changed & Improved
13
- - **100% Dynamic Test Lead Generation**:
14
- - Removed all hardcoded mock client data (`9585950059`, `Sports Injury Rehabilitation`, `samya-sports-clinic`, `Bengaluru`, `Test Patient`).
15
- - `tester.js`: `domain` dynamically resolves from `config.domain`, URL hostname, or folder name (`path.basename(rootDir)`).
16
- - `tester.js`: `phone`, `service`, `location`, and `email` dynamically pull from detected website metadata and actual form fields with clean neutral fallbacks.
17
- - `scanner.js`: Removed hardcoded `Bengaluru` fallback, dynamically extracts `detectedDomain` and `detectedService`.
18
- - `app.js` & `index.html`: Web GUI test cards dynamically pre-fill phone, service, and location from live site scan results instead of static mock strings.
19
- - `bin/cli.js`: CLI version output dynamically loads from `package.json`.
20
- - **Enhanced Test Suite Resilience**:
21
- - `multipage.test.js`: Added transient in-process HTTP mock server to guarantee 100% offline self-contained test execution.
22
- - Added Test 13 in `injector.test.js` verifying dynamic test lead dispatch parameters.
23
-
24
- ---
25
-
26
10
  ## [1.0.0] - 2026-09-14
27
11
 
28
12
  ### Initial Release
package/bin/cli.js CHANGED
@@ -26,7 +26,6 @@
26
26
  */
27
27
 
28
28
  const path = require('path');
29
- const pkg = require('../package.json');
30
29
  const { runTerminalWizard } = require('../src/cli/terminal');
31
30
  const { startGuiServer } = require('../src/gui/server');
32
31
  const { restoreBackup, restoreLatestBackup, listBackups, manualBackup } = require('../src/core/rollback');
@@ -45,7 +44,7 @@ const rootDir = positionalArgs.length > 0 ? path.resolve(positionalArgs[0]) : pr
45
44
  // ============================================================================
46
45
  if (args.includes('--help') || args.includes('-h')) {
47
46
  console.log(`
48
- ⚡ BUZL TRACKING & FORM DISPATCHER CLI (v${pkg.version})
47
+ ⚡ BUZL TRACKING & FORM DISPATCHER CLI (v1.0.0)
49
48
 
50
49
  USAGE:
51
50
  $ npx buzl-tracker [dir] Launch interactive terminal wizard
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mahe_pkm/buzl-capi",
3
- "version": "0.1.2",
3
+ "version": "1.0.1",
4
4
  "description": "All-in-one CLI & GUI for automated GTM, Meta Pixel/CAPI, Google Sheets Form Sync, and Zoho CRM injection with self-testing.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -244,25 +244,14 @@ async function runTerminalWizard(rootDir) {
244
244
  return;
245
245
  }
246
246
 
247
- console.log(`\n Testing Form: ${colors.cyan(selectedForm.selector || selectedForm.formId || 'Form')}`);
248
- const defaultPhone = selectedForm.detectedWhatsapp || scan.detectedWhatsapp || '';
249
- const phonePrompt = defaultPhone ? ` Enter test phone [${defaultPhone}]: ` : ' Enter test phone: ';
250
- const testPhone = (await askQuestion(rl, phonePrompt)).trim() || defaultPhone;
251
- const testName = (await askQuestion(rl, ' Enter test name [Test Lead]: ')).trim() || 'Test Lead';
247
+ console.log(`\n Testing Form: ${colors.cyan(selectedForm.selector)}`);
248
+ const testPhone = (await askQuestion(rl, ' Enter test phone [9585950059]: ')).trim() || '9585950059';
249
+ const testName = (await askQuestion(rl, ' Enter test name [Buzl Test Lead]: ')).trim() || 'Buzl Test Lead';
252
250
 
253
251
  const formFields = { phone: testPhone, name: testName, formId: selectedForm.formId };
254
252
  selectedForm.inputs.forEach(inp => {
255
253
  if (!formFields[inp.name]) {
256
- const lower = (inp.name || '').toLowerCase();
257
- if (lower.includes('service') || lower.includes('inquiry') || lower.includes('treatment') || lower.includes('subject')) {
258
- formFields[inp.name] = selectedForm.formId || 'General Inquiry';
259
- } else if (lower.includes('email') || lower.includes('mail')) {
260
- formFields[inp.name] = 'test-lead@example.com';
261
- } else if (lower.includes('city') || lower.includes('loc')) {
262
- formFields[inp.name] = scan.detectedLocation || '';
263
- } else {
264
- formFields[inp.name] = 'Test Value';
265
- }
254
+ formFields[inp.name] = inp.name.includes('service') ? 'Sports Injury Rehabilitation' : 'Test Value';
266
255
  }
267
256
  });
268
257
 
@@ -144,7 +144,7 @@ function detectSiteLocation(rootDir, htmlContent = '') {
144
144
  }
145
145
  }
146
146
 
147
- return '';
147
+ return 'Bengaluru';
148
148
  }
149
149
 
150
150
  /**
@@ -429,24 +429,6 @@ function scanProject(rootDir) {
429
429
  return dir === '.' ? '/' : `/${dir}`;
430
430
  }))).sort();
431
431
 
432
- const cleanDirName = path.basename(rootDir).toLowerCase().replace(/[^a-z0-9_-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
433
- const detectedDomain = cleanDirName || 'landing-page';
434
-
435
- let detectedService = '';
436
- for (const form of allDiscoveredForms) {
437
- const sInput = (form.inputs || []).find(i => {
438
- const lower = (i.name || '').toLowerCase();
439
- return lower.includes('service') || lower.includes('inquiry') || lower.includes('treatment') || lower.includes('course') || lower.includes('department');
440
- });
441
- if (sInput) {
442
- detectedService = form.id || form.selector || 'Website Inquiry';
443
- break;
444
- }
445
- }
446
- if (!detectedService && allDiscoveredForms.length > 0) {
447
- detectedService = allDiscoveredForms[0].id || 'General Inquiry';
448
- }
449
-
450
432
  const liveState = {
451
433
  gtm: { active: !!gtmId, id: gtmId },
452
434
  meta: { active: !!metaPixelId, id: metaPixelId },
@@ -462,9 +444,6 @@ function scanProject(rootDir) {
462
444
  number: (waCfg && waCfg.number) || '',
463
445
  detectedNumber: detectedWhatsapp || ''
464
446
  },
465
- detectedLocation: detectedLocation || '',
466
- detectedDomain: detectedDomain,
467
- detectedService: detectedService || 'General Inquiry',
468
447
  forms: allDiscoveredForms,
469
448
  formArchetypes: formArchetypes,
470
449
  directories: directories,
@@ -486,10 +465,8 @@ function scanProject(rootDir) {
486
465
  filesWithGtm,
487
466
  filesWithMeta,
488
467
  uniqueFields,
489
- detectedLocation: detectedLocation || '',
468
+ detectedLocation,
490
469
  detectedWhatsapp,
491
- detectedDomain,
492
- detectedService: detectedService || 'General Inquiry',
493
470
  existingConfig,
494
471
  liveState,
495
472
  forms: allDiscoveredForms,
@@ -140,11 +140,9 @@ async function runVerification(rootDir, htmlFiles, config) {
140
140
  async function testDispatch(arg1, arg2 = {}, arg3 = {}) {
141
141
  let config = arg1;
142
142
  let sampleLead = arg2;
143
- let rootDir = '';
144
143
 
145
144
  // Polymorphic support: if called as (rootDir, config, sampleLead)
146
145
  if (typeof arg1 === 'string' && typeof arg2 === 'object') {
147
- rootDir = arg1;
148
146
  config = arg2;
149
147
  sampleLead = arg3;
150
148
  }
@@ -152,10 +150,10 @@ async function testDispatch(arg1, arg2 = {}, arg3 = {}) {
152
150
  if (!sampleLead) sampleLead = {};
153
151
 
154
152
  const leadId = sampleLead.leadId || ('test-lead-' + Date.now());
155
- const name = sampleLead.name || 'Test Lead';
156
- const phone = sampleLead.phone || config.whatsappNumber || (config.whatsapp && config.whatsapp.number) || '';
157
- const location = sampleLead.location || config.siteLocation || '';
158
- const service = sampleLead.service || 'General Inquiry';
153
+ const name = sampleLead.name || 'Buzl Test Lead';
154
+ const phone = sampleLead.phone || '9585950059';
155
+ const location = sampleLead.location || config.siteLocation || 'Bengaluru';
156
+ const service = sampleLead.service || 'General Consultation';
159
157
 
160
158
  const results = {
161
159
  leadId,
@@ -175,7 +173,7 @@ async function testDispatch(arg1, arg2 = {}, arg3 = {}) {
175
173
  siteLocation: config.siteLocation || location,
176
174
  phone: phone,
177
175
  service: service,
178
- email: sampleLead.email || config.notificationEmail || 'test-lead@example.com',
176
+ email: sampleLead.email || 'test@gobuzl.com',
179
177
  source: service,
180
178
  utm: { source: 'live_test_button', medium: 'gui_test', campaign: 'buzl_verification' },
181
179
  eventSourceUrl: sampleLead.eventSourceUrl || 'http://localhost:3333/test',
@@ -231,15 +229,9 @@ async function testDispatch(arg1, arg2 = {}, arg3 = {}) {
231
229
 
232
230
  if (capiEndpoint && authUser) {
233
231
  try {
234
- const resolvedDomain = sampleLead.domain ||
235
- config.domain ||
236
- (config.siteUrl ? new URL(config.siteUrl).hostname : '') ||
237
- (rootDir ? path.basename(rootDir).toLowerCase().replace(/[^a-z0-9_-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '') : '') ||
238
- 'landing-page';
239
-
240
232
  const capiPayload = {
241
233
  leadId: leadId,
242
- domain: resolvedDomain,
234
+ domain: 'samya-sports-clinic',
243
235
  eventName: 'Lead',
244
236
  eventTime: Math.floor(Date.now() / 1000),
245
237
  actionSource: 'website',
@@ -327,10 +319,10 @@ async function testDispatch(arg1, arg2 = {}, arg3 = {}) {
327
319
  async function testIndividualForm(rootDir, formId, formFields = {}, config = {}, extraOpts = {}) {
328
320
  const leadId = 'test-' + (formId || 'form').replace(/[^a-zA-Z0-9_-]/g, '') + '-' + Date.now();
329
321
 
330
- const name = formFields.name || formFields.fullName || 'Test Lead';
331
- const phone = formFields.phone || formFields.mobile || config.whatsappNumber || (config.whatsapp && config.whatsapp.number) || '';
332
- const location = formFields.location || formFields.city || config.siteLocation || '';
333
- const service = formFields.service || formFields.subject || formFields.inquiry || formId || 'General Inquiry';
322
+ const name = formFields.name || formFields.fullName || 'Buzl Form Test Lead';
323
+ const phone = formFields.phone || formFields.mobile || '9585950059';
324
+ const location = formFields.location || formFields.city || config.siteLocation || 'Bengaluru';
325
+ const service = formFields.service || formFields.subject || formId || 'General Inquiry';
334
326
  const pagePath = extraOpts.pagePath || formFields.pagePath || '/';
335
327
 
336
328
  const sampleLead = {
@@ -346,7 +338,7 @@ async function testIndividualForm(rootDir, formId, formFields = {}, config = {},
346
338
  rawFields: Object.assign({}, formFields, { formId, pagePath, isTest: true })
347
339
  };
348
340
 
349
- return await testDispatch(rootDir, config, sampleLead);
341
+ return await testDispatch(config, sampleLead);
350
342
  }
351
343
 
352
344
  module.exports = {
@@ -20,10 +20,6 @@ document.addEventListener('DOMContentLoaded', () => {
20
20
  const testLeadName = document.getElementById('testLeadName');
21
21
  const testLeadService = document.getElementById('testLeadService');
22
22
 
23
- [testLeadPhone, testLeadName, testLeadService].forEach(el => {
24
- if (el) el.addEventListener('input', () => { el.dataset.userEdited = 'true'; });
25
- });
26
-
27
23
  // Individual Form elements
28
24
  const formsCountBadge = document.getElementById('formsCountBadge');
29
25
  const individualFormsList = document.getElementById('individualFormsList');
@@ -106,18 +102,10 @@ document.addEventListener('DOMContentLoaded', () => {
106
102
  updateLiveStateBar(data.liveState, data.rootDir);
107
103
 
108
104
  // Auto-detect site location
109
- if (data.detectedLocation && siteLocationInput && !siteLocationInput.dataset.userEdited) {
105
+ if (data.detectedLocation && siteLocationInput && !siteLocationInput.value) {
110
106
  siteLocationInput.value = data.detectedLocation;
111
107
  }
112
108
 
113
- // Auto-detect phone and service for quick test dispatch
114
- if (testLeadPhone && !testLeadPhone.dataset.userEdited) {
115
- testLeadPhone.value = data.detectedWhatsapp || (data.liveState && data.liveState.whatsapp && data.liveState.whatsapp.detectedNumber) || '';
116
- }
117
- if (testLeadService && !testLeadService.dataset.userEdited) {
118
- testLeadService.value = data.detectedService || 'General Inquiry';
119
- }
120
-
121
109
  // Populate dynamic fields checklist
122
110
  if (dynamicFieldsChecklist && data.uniqueFields) {
123
111
  dynamicFieldsChecklist.innerHTML = '';
@@ -421,19 +409,12 @@ document.addEventListener('DOMContentLoaded', () => {
421
409
 
422
410
  // Build sample test input controls
423
411
  const inputElements = f.inputs.map(i => {
424
- let sampleVal = 'Test Value';
412
+ let sampleVal = 'Test';
425
413
  const lower = i.name.toLowerCase();
426
- if (lower.includes('phone') || lower.includes('mobile')) {
427
- sampleVal = f.detectedWhatsapp || (currentScanData && currentScanData.detectedWhatsapp) || '';
428
- } else if (lower.includes('name')) {
429
- sampleVal = `Test Lead ${idx + 1}`;
430
- } else if (lower.includes('mail')) {
431
- sampleVal = 'test-lead@example.com';
432
- } else if (lower.includes('service') || lower.includes('inquiry') || lower.includes('treatment') || lower.includes('subject')) {
433
- sampleVal = f.formTitle || f.id || (currentScanData && currentScanData.detectedService) || 'General Inquiry';
434
- } else if (lower.includes('city') || lower.includes('loc')) {
435
- sampleVal = (currentScanData && currentScanData.detectedLocation) || '';
436
- }
414
+ if (lower.includes('phone') || lower.includes('mobile')) sampleVal = '9585950059';
415
+ else if (lower.includes('name')) sampleVal = `Test Patient ${idx + 1}`;
416
+ else if (lower.includes('mail')) sampleVal = 'test@gobuzl.com';
417
+ else if (lower.includes('service')) sampleVal = 'Sports Injury Rehabilitation';
437
418
 
438
419
  return `
439
420
  <div class="form-field-input-group">
@@ -852,10 +833,9 @@ document.addEventListener('DOMContentLoaded', () => {
852
833
  if (btnTestSubmit) {
853
834
  btnTestSubmit.addEventListener('click', async () => {
854
835
  const config = getCurrentConfig();
855
- const phone = testLeadPhone.value.trim() || (currentScanData && currentScanData.detectedWhatsapp) || '';
856
- const name = testLeadName.value.trim() || 'Test Lead';
857
- const service = testLeadService.value.trim() || (currentScanData && currentScanData.detectedService) || 'General Inquiry';
858
- const loc = (siteLocationInput ? siteLocationInput.value.trim() : '') || (currentScanData && currentScanData.detectedLocation) || '';
836
+ const phone = testLeadPhone.value.trim() || '9585950059';
837
+ const name = testLeadName.value.trim() || 'Buzl Test Lead';
838
+ const service = testLeadService.value.trim() || 'Sports Injury Rehabilitation';
859
839
 
860
840
  btnTestSubmit.disabled = true;
861
841
  btnTestSubmit.innerHTML = '<svg class="icon-sm icon-spin"><use href="#icon-refresh"/></svg> <span>Sending Live Test Lead...</span>';
@@ -874,7 +854,7 @@ document.addEventListener('DOMContentLoaded', () => {
874
854
  phone,
875
855
  name,
876
856
  service,
877
- location: loc
857
+ location: siteLocationInput ? siteLocationInput.value.trim() : 'Bengaluru'
878
858
  }
879
859
  })
880
860
  });
@@ -305,7 +305,7 @@
305
305
  </div>
306
306
  <div class="form-group">
307
307
  <label for="siteLocation">Default Site Location (Fallback for Column B)</label>
308
- <input type="text" id="siteLocation" placeholder="Auto-detected from site or enter location">
308
+ <input type="text" id="siteLocation" placeholder="e.g. Sahakar Nagar, Bengaluru">
309
309
  <small class="helper-text">Auto-detected from metadata. Fills Column B if forms omit location.</small>
310
310
  </div>
311
311
 
@@ -470,16 +470,16 @@
470
470
  <div class="form-row">
471
471
  <div class="form-group">
472
472
  <label for="testLeadPhone">Phone Number</label>
473
- <input type="text" id="testLeadPhone" placeholder="Auto-detected or enter phone">
473
+ <input type="text" id="testLeadPhone" value="9585950059">
474
474
  </div>
475
475
  <div class="form-group">
476
476
  <label for="testLeadName">Full Name</label>
477
- <input type="text" id="testLeadName" value="Test Lead">
477
+ <input type="text" id="testLeadName" value="Buzl Test Lead">
478
478
  </div>
479
479
  </div>
480
480
  <div class="form-group" style="margin-top: 8px;">
481
481
  <label for="testLeadService">Service / Inquiry</label>
482
- <input type="text" id="testLeadService" placeholder="Auto-detected or enter inquiry">
482
+ <input type="text" id="testLeadService" value="Sports Injury Rehabilitation">
483
483
  </div>
484
484
  <button type="button" id="btnTestSubmit" class="btn btn-primary" style="width: 100%; margin-top: 12px;">
485
485
  <svg class="icon-sm"><use href="#icon-send"/></svg>