open-local-audit 0.76.0 → 0.78.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.
- package/CHANGELOG.md +518 -497
- package/LICENSE +21 -21
- package/README.md +543 -538
- package/dist/audit.d.ts +2 -0
- package/dist/audit.js +13 -0
- package/dist/audit.js.map +1 -1
- package/dist/cli.js +37 -12
- package/dist/cli.js.map +1 -1
- package/dist/compare.d.ts +17 -1
- package/dist/compare.js +170 -6
- package/dist/compare.js.map +1 -1
- package/dist/contact.d.ts +7 -0
- package/dist/contact.js +106 -2
- package/dist/contact.js.map +1 -1
- package/dist/discovery.d.ts +1 -0
- package/dist/discovery.js +92 -6
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/local-business-types.d.ts +16 -0
- package/dist/local-business-types.js +324 -0
- package/dist/local-business-types.js.map +1 -0
- package/dist/overture.js +28 -28
- package/dist/pdf.js +2 -1
- package/dist/pdf.js.map +1 -1
- package/dist/pitch-brief.d.ts +33 -0
- package/dist/pitch-brief.js +160 -0
- package/dist/pitch-brief.js.map +1 -0
- package/dist/report-pack.js +2 -1
- package/dist/report-pack.js.map +1 -1
- package/dist/reporters.js +4 -2
- package/dist/reporters.js.map +1 -1
- package/dist/rules.js +165 -14
- package/dist/rules.js.map +1 -1
- package/dist/shortlist-runner.d.ts +4 -0
- package/dist/shortlist-runner.js +10 -0
- package/dist/shortlist-runner.js.map +1 -1
- package/dist/tls-probe.d.ts +2 -0
- package/dist/tls-probe.js +46 -0
- package/dist/tls-probe.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/website-enrichment.d.ts +3 -0
- package/dist/website-enrichment.js +27 -1
- package/dist/website-enrichment.js.map +1 -1
- package/dist/workflow.d.ts +1 -1
- package/dist/workflow.js +2 -2
- package/dist/workflow.js.map +1 -1
- package/docs/guides/free-discovery.md +151 -151
- package/package.json +1 -1
package/dist/compare.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
3
|
import { brandName, escapeCell, escapeHtml, overallScore, severityRank } from "./reporters.js";
|
|
4
4
|
function siteHost(url) {
|
|
5
5
|
return new URL(url).hostname.toLowerCase().replace(/^www\./, "");
|
|
@@ -27,7 +27,7 @@ export async function readComparisonReport(path) {
|
|
|
27
27
|
}
|
|
28
28
|
let report;
|
|
29
29
|
try {
|
|
30
|
-
report = JSON.parse(content.replace(
|
|
30
|
+
report = JSON.parse(content.replace(/^\uFEFF/, ""));
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
if (error instanceof SyntaxError) {
|
|
@@ -44,7 +44,51 @@ export async function readComparisonReport(path) {
|
|
|
44
44
|
!Array.isArray(report.findings)) {
|
|
45
45
|
throw new Error(`${reportPath} is not an Open Local Audit JSON report`);
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
// Screenshot paths are written relative to the report directory. Only files inside that directory are used, so a
|
|
48
|
+
// report from elsewhere cannot pull unrelated local images into a customer-facing comparison.
|
|
49
|
+
const reportDir = dirname(reportPath);
|
|
50
|
+
const inside = (path) => {
|
|
51
|
+
if (typeof path !== "string" || !path.trim()) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const resolved = resolve(reportDir, path);
|
|
55
|
+
const fromReport = relative(reportDir, resolved);
|
|
56
|
+
return fromReport && !fromReport.startsWith("..") && !isAbsolute(fromReport) ? resolved : undefined;
|
|
57
|
+
};
|
|
58
|
+
const visualEvidence = Array.isArray(report.visualEvidence)
|
|
59
|
+
? report.visualEvidence.flatMap((item) => {
|
|
60
|
+
const path = inside(item?.path);
|
|
61
|
+
const screenshot = inside(item?.screenshotPath);
|
|
62
|
+
return path ? [{ ...item, path, ...(screenshot ? { screenshotPath: screenshot } : { screenshotPath: undefined }) }] : [];
|
|
63
|
+
})
|
|
64
|
+
: undefined;
|
|
65
|
+
return { ...report, visualEvidence };
|
|
66
|
+
}
|
|
67
|
+
function screenshotPath(report) {
|
|
68
|
+
return report.visualEvidence?.find((item) => item.screenshotPath)?.screenshotPath;
|
|
69
|
+
}
|
|
70
|
+
const pngSignature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
71
|
+
async function readScreenshot(path) {
|
|
72
|
+
if (!path) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
let data;
|
|
76
|
+
try {
|
|
77
|
+
data = await readFile(path);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
if (data.subarray(0, 8).equals(pngSignature)) {
|
|
83
|
+
return { data, type: "png" };
|
|
84
|
+
}
|
|
85
|
+
return data[0] === 0xff && data[1] === 0xd8 ? { data, type: "jpeg" } : undefined;
|
|
86
|
+
}
|
|
87
|
+
export async function loadComparisonScreenshots(comparison) {
|
|
88
|
+
return {
|
|
89
|
+
before: await readScreenshot(comparison.screenshots.before),
|
|
90
|
+
after: await readScreenshot(comparison.screenshots.after)
|
|
91
|
+
};
|
|
48
92
|
}
|
|
49
93
|
export function compareReports(before, after) {
|
|
50
94
|
if (siteHost(before.finalUrl) !== siteHost(after.finalUrl)) {
|
|
@@ -84,7 +128,8 @@ export function compareReports(before, after) {
|
|
|
84
128
|
scores,
|
|
85
129
|
fixed: bySeverity(before.findings.filter((finding) => !afterIds.has(finding.id))),
|
|
86
130
|
introduced: bySeverity(after.findings.filter((finding) => !beforeIds.has(finding.id))),
|
|
87
|
-
remaining: bySeverity(after.findings.filter((finding) => beforeIds.has(finding.id)))
|
|
131
|
+
remaining: bySeverity(after.findings.filter((finding) => beforeIds.has(finding.id))),
|
|
132
|
+
screenshots: { before: screenshotPath(before), after: screenshotPath(after) }
|
|
88
133
|
};
|
|
89
134
|
}
|
|
90
135
|
export function renderComparisonJson(comparison) {
|
|
@@ -123,7 +168,18 @@ export function renderComparisonMarkdown(comparison, options = {}) {
|
|
|
123
168
|
"",
|
|
124
169
|
...section("Fixed Issues", "No issues from the earlier audit were fixed.", ["Severity", "Finding"], comparison.fixed.map((finding) => [finding.severity, finding.title])),
|
|
125
170
|
...section("Still Open", "No issues from the earlier audit are still open.", ["Severity", "Finding", "Recommendation"], comparison.remaining.map((finding) => [finding.severity, finding.title, finding.recommendation])),
|
|
126
|
-
...section("New Issues", "No new issues were found.", ["Severity", "Finding", "Evidence", "Recommendation"], comparison.introduced.map((finding) => [finding.severity, finding.title, evidence(finding), finding.recommendation]))
|
|
171
|
+
...section("New Issues", "No new issues were found.", ["Severity", "Finding", "Evidence", "Recommendation"], comparison.introduced.map((finding) => [finding.severity, finding.title, evidence(finding), finding.recommendation])),
|
|
172
|
+
...(comparison.screenshots.before || comparison.screenshots.after
|
|
173
|
+
? [
|
|
174
|
+
"## Screenshots",
|
|
175
|
+
"",
|
|
176
|
+
`- Before: ${comparison.screenshots.before ? "Captured" : "Not captured"}`,
|
|
177
|
+
`- After: ${comparison.screenshots.after ? "Captured" : "Not captured"}`,
|
|
178
|
+
"",
|
|
179
|
+
"Use the HTML or PDF format to see them side by side.",
|
|
180
|
+
""
|
|
181
|
+
]
|
|
182
|
+
: [])
|
|
127
183
|
];
|
|
128
184
|
return `${lines.join("\n")}\n`;
|
|
129
185
|
}
|
|
@@ -148,6 +204,19 @@ ${rows.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).joi
|
|
|
148
204
|
const footer = brand?.footerText || brand?.contact
|
|
149
205
|
? `<footer class="meta">${escapeHtml([brand.footerText, brand.contact].filter(Boolean).join(" | "))}</footer>\n`
|
|
150
206
|
: "";
|
|
207
|
+
const figure = (label, scannedAt, screenshot) => {
|
|
208
|
+
const image = screenshot
|
|
209
|
+
? `<img src="data:image/${screenshot.type};base64,${screenshot.data.toString("base64")}" alt="${escapeHtml(label)} screenshot">`
|
|
210
|
+
: "<p>Not captured</p>";
|
|
211
|
+
return `<figure>${image}<figcaption>${escapeHtml(label)} (${escapeHtml(scannedAt)})</figcaption></figure>`;
|
|
212
|
+
};
|
|
213
|
+
const screenshots = options.screenshots?.before || options.screenshots?.after
|
|
214
|
+
? ` <section>
|
|
215
|
+
<h2>Before and After</h2>
|
|
216
|
+
<div class="shots">${figure("Before", comparison.beforeScannedAt, options.screenshots.before)}${figure("After", comparison.afterScannedAt, options.screenshots.after)}</div>
|
|
217
|
+
</section>
|
|
218
|
+
`
|
|
219
|
+
: "";
|
|
151
220
|
return `<!doctype html>
|
|
152
221
|
<html lang="en">
|
|
153
222
|
<head>
|
|
@@ -171,6 +240,10 @@ ${rows.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).joi
|
|
|
171
240
|
th, td { border-bottom: 1px solid var(--line); padding: 0.65rem; text-align: left; vertical-align: top; }
|
|
172
241
|
th { background: var(--panel); color: var(--muted); font-size: 0.82rem; text-transform: uppercase; }
|
|
173
242
|
tr:last-child td { border-bottom: 0; }
|
|
243
|
+
.shots { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
|
|
244
|
+
figure { margin: 0; }
|
|
245
|
+
figure img { border: 1px solid var(--line); border-radius: 8px; display: block; max-height: 900px; object-fit: cover; object-position: top; width: 100%; }
|
|
246
|
+
figcaption { color: var(--muted); margin-top: 0.4rem; }
|
|
174
247
|
</style>
|
|
175
248
|
</head>
|
|
176
249
|
<body>
|
|
@@ -202,9 +275,100 @@ ${rows.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).joi
|
|
|
202
275
|
<h2>New Issues</h2>
|
|
203
276
|
${table("No new issues were found.", ["Severity", "Finding", "Evidence", "Recommendation"], comparison.introduced.map((finding) => [finding.severity, finding.title, evidence(finding), finding.recommendation]))}
|
|
204
277
|
</section>
|
|
205
|
-
${footer} </main>
|
|
278
|
+
${screenshots}${footer} </main>
|
|
206
279
|
</body>
|
|
207
280
|
</html>
|
|
208
281
|
`;
|
|
209
282
|
}
|
|
283
|
+
export async function renderComparisonPdf(comparison, options = {}) {
|
|
284
|
+
const brand = options.brand;
|
|
285
|
+
const name = brandName(brand);
|
|
286
|
+
const primaryColor = brand?.primaryColor ?? "#145a73";
|
|
287
|
+
const accentColor = brand?.accentColor ?? "#2f7d5f";
|
|
288
|
+
// pdfkit is loaded on demand so the CLI does not pay for it on every start.
|
|
289
|
+
const { default: PDFDocument } = await import("pdfkit");
|
|
290
|
+
const doc = new PDFDocument({ size: "A4", margin: 48, info: { Title: `${name} Progress Report`, Author: name } });
|
|
291
|
+
const chunks = [];
|
|
292
|
+
doc.on("data", (chunk) => chunks.push(chunk));
|
|
293
|
+
const finished = new Promise((resolveBuffer, reject) => {
|
|
294
|
+
doc.on("end", () => resolveBuffer(Buffer.concat(chunks)));
|
|
295
|
+
doc.on("error", reject);
|
|
296
|
+
});
|
|
297
|
+
const sectionTitle = (title) => {
|
|
298
|
+
doc.moveDown(1);
|
|
299
|
+
doc.font("Helvetica-Bold").fontSize(14).fillColor(primaryColor).text(title);
|
|
300
|
+
doc.moveDown(0.3);
|
|
301
|
+
doc.font("Helvetica").fontSize(10).fillColor("#172026");
|
|
302
|
+
};
|
|
303
|
+
const findingList = (findings, empty, withRecommendation) => {
|
|
304
|
+
if (findings.length === 0) {
|
|
305
|
+
doc.text(empty);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
for (const finding of findings) {
|
|
309
|
+
doc.font("Helvetica-Bold").text(`${finding.severity.toUpperCase()} - ${finding.title}`);
|
|
310
|
+
if (withRecommendation) {
|
|
311
|
+
doc.font("Helvetica").text(finding.recommendation);
|
|
312
|
+
}
|
|
313
|
+
doc.font("Helvetica").moveDown(0.3);
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
doc.rect(0, 0, doc.page.width, 92).fill(primaryColor);
|
|
317
|
+
doc.fillColor("#ffffff").font("Helvetica-Bold").fontSize(22).text(`${name} Progress Report`, 48, 32);
|
|
318
|
+
doc.font("Helvetica").fontSize(10).text(comparison.url, 48, 60);
|
|
319
|
+
doc.fillColor("#172026").fontSize(10).text("", 48, 118);
|
|
320
|
+
doc.text(`Before: ${comparison.beforeScannedAt}`);
|
|
321
|
+
doc.text(`After: ${comparison.afterScannedAt}`);
|
|
322
|
+
doc.text(`Profile: ${comparison.profile}`);
|
|
323
|
+
doc.moveDown(0.8);
|
|
324
|
+
doc
|
|
325
|
+
.font("Helvetica-Bold")
|
|
326
|
+
.fontSize(18)
|
|
327
|
+
.fillColor(accentColor)
|
|
328
|
+
.text(`Overall Health: ${comparison.overall.before} -> ${comparison.overall.after} (${signed(comparison.overall.change)})`);
|
|
329
|
+
doc
|
|
330
|
+
.font("Helvetica")
|
|
331
|
+
.fontSize(10)
|
|
332
|
+
.fillColor("#172026")
|
|
333
|
+
.text(`Fixed: ${comparison.fixed.length} Still open: ${comparison.remaining.length} New: ${comparison.introduced.length}`);
|
|
334
|
+
sectionTitle("Score Changes");
|
|
335
|
+
for (const score of Object.values(comparison.scores)) {
|
|
336
|
+
doc.text(`${score.label}: ${score.before}/${score.max} -> ${score.after}/${score.max} (${signed(score.change)})`);
|
|
337
|
+
}
|
|
338
|
+
sectionTitle("Fixed Issues");
|
|
339
|
+
findingList(comparison.fixed, "No issues from the earlier audit were fixed.", false);
|
|
340
|
+
sectionTitle("Still Open");
|
|
341
|
+
findingList(comparison.remaining, "No issues from the earlier audit are still open.", true);
|
|
342
|
+
sectionTitle("New Issues");
|
|
343
|
+
findingList(comparison.introduced, "No new issues were found.", true);
|
|
344
|
+
const shots = [
|
|
345
|
+
["Before", comparison.beforeScannedAt, options.screenshots?.before],
|
|
346
|
+
["After", comparison.afterScannedAt, options.screenshots?.after]
|
|
347
|
+
];
|
|
348
|
+
if (shots.some(([, , shot]) => shot)) {
|
|
349
|
+
doc.addPage();
|
|
350
|
+
doc.font("Helvetica-Bold").fontSize(14).fillColor(primaryColor).text("Before and After");
|
|
351
|
+
const top = doc.y + 8;
|
|
352
|
+
const width = (doc.page.width - 48 * 2 - 16) / 2;
|
|
353
|
+
shots.forEach(([label, scannedAt, shot], index) => {
|
|
354
|
+
const x = 48 + index * (width + 16);
|
|
355
|
+
doc.font("Helvetica").fontSize(9).fillColor("#5f6b75").text(`${label} (${scannedAt})`, x, top, { width });
|
|
356
|
+
if (shot) {
|
|
357
|
+
doc.image(shot.data, x, top + 16, { fit: [width, doc.page.height - top - 96], align: "center" });
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
doc.text("Not captured", x, top + 16, { width });
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
if (brand?.footerText || brand?.contact) {
|
|
365
|
+
doc
|
|
366
|
+
.font("Helvetica")
|
|
367
|
+
.fontSize(8)
|
|
368
|
+
.fillColor("#5f6b75")
|
|
369
|
+
.text([brand.footerText, brand.contact].filter(Boolean).join(" | "), 48, doc.page.height - 64, { width: doc.page.width - 96 });
|
|
370
|
+
}
|
|
371
|
+
doc.end();
|
|
372
|
+
return await finished;
|
|
373
|
+
}
|
|
210
374
|
//# sourceMappingURL=compare.js.map
|
package/dist/compare.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAuB/F,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,QAAmB;IACrC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY;IACrD,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACrC,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,8BAA8B,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,gBAAgB,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,MAA4B,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAyB,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,oBAAoB,CAAC,CAAC;QACrD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IACE,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC9B,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;QACjC,MAAM,CAAC,MAAM,KAAK,IAAI;QACtB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,yCAAyC,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,KAAkB;IACpE,IAAI,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,QAAQ,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC;IAClD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC;IAChD,IAAI,aAAa,KAAK,YAAY,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,aAAa,QAAQ,YAAY,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAqE,EAAE,CAAC;QACjI,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,QAAQ,CAAC,GAAG;gBACjB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,QAAQ,CAAC,KAAK;gBACtB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK;aACrC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,QAAQ;QACnB,OAAO,EAAE,YAAY;QACrB,eAAe,EAAE,MAAM,CAAC,SAAS;QACjC,cAAc,EAAE,KAAK,CAAC,SAAS;QAC/B,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,aAAa,EAAE;QAC7F,MAAM;QACN,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACjF,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;KACrF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAA2B;IAC9D,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,UAA2B,EAAE,UAA+B,EAAE;IACrG,MAAM,QAAQ,GAAG,CAAC,OAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjH,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,KAAa,EAAE,MAAgB,EAAE,IAAgB,EAAY,EAAE,CAAC;QAC9F,MAAM,KAAK,EAAE;QACb,EAAE;QACF,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YACnB,CAAC,CAAC,CAAC,KAAK,CAAC;YACT,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAChJ,EAAE;KACH,CAAC;IAEF,MAAM,KAAK,GAAG;QACZ,KAAK,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB;QAC/C,EAAE;QACF,WAAW,UAAU,CAAC,GAAG,EAAE;QAC3B,aAAa,UAAU,CAAC,eAAe,EAAE;QACzC,YAAY,UAAU,CAAC,cAAc,EAAE;QACvC,cAAc,UAAU,CAAC,OAAO,EAAE;QAClC,EAAE;QACF,YAAY;QACZ,EAAE;QACF,qBAAqB,UAAU,CAAC,OAAO,CAAC,MAAM,WAAW,UAAU,CAAC,OAAO,CAAC,KAAK,SAAS,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG;QAC9H,mBAAmB,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE;QAC5C,iBAAiB,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE;QAC9C,iBAAiB,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE;QAC/C,EAAE;QACF,kBAAkB;QAClB,EAAE;QACF,wCAAwC;QACxC,8BAA8B;QAC9B,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CACnI;QACD,EAAE;QACF,GAAG,OAAO,CACR,cAAc,EACd,8CAA8C,EAC9C,CAAC,UAAU,EAAE,SAAS,CAAC,EACvB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CACrE;QACD,GAAG,OAAO,CACR,YAAY,EACZ,kDAAkD,EAClD,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,EACzC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CACjG;QACD,GAAG,OAAO,CACR,YAAY,EACZ,2BAA2B,EAC3B,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,CAAC,EACrD,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CACrH;KACF,CAAC;IAEF,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAA2B,EAAE,UAA+B,EAAE;IACjG,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,MAAgB,EAAE,IAAgB,EAAU,EAAE,CAC1E,IAAI,CAAC,MAAM,KAAK,CAAC;QACf,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,MAAM;QAC/B,CAAC,CAAC;mBACW,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;EAE9E,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;aAE3F,CAAC;IACZ,MAAM,QAAQ,GAAG,CAAC,OAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjH,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAChE,KAAK,CAAC,KAAK;QACX,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;QAC7B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,MAAM,MAAM,GACV,KAAK,EAAE,UAAU,IAAI,KAAK,EAAE,OAAO;QACjC,CAAC,CAAC,wBAAwB,UAAU,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa;QAChH,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;;;;;aAKI,UAAU,CAAC,IAAI,CAAC,sBAAsB,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;;mHAEsC,UAAU,CAAC,KAAK,EAAE,YAAY,IAAI,SAAS,CAAC,eAAe,UAAU,CAAC,KAAK,EAAE,WAAW,IAAI,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;6BAqB5L,UAAU,CAAC,IAAI,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC;8BACE,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,cAAc,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,gBAAgB,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;;qEAEzI,UAAU,CAAC,OAAO,CAAC,MAAM,WAAW,UAAU,CAAC,OAAO,CAAC,KAAK,kBAAkB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;iFACnG,UAAU,CAAC,KAAK,CAAC,MAAM;iEACvC,UAAU,CAAC,SAAS,CAAC,MAAM;iEAC3B,UAAU,CAAC,UAAU,CAAC,MAAM;;;;;MAKvF,KAAK,CAAC,gCAAgC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;;;;MAI7F,KAAK,CAAC,8CAA8C,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;;;;MAIpJ,KAAK,CAAC,kDAAkD,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;;;;MAItM,KAAK,CAAC,2BAA2B,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;;EAEnN,MAAM;;;CAGP,CAAC;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"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"}
|
package/dist/contact.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
import { type CheerioAPI } from "cheerio";
|
|
1
2
|
import type { PublicContact } from "./types.js";
|
|
3
|
+
export declare function hasContactOrBookingLink($: CheerioAPI, pageUrl: string): boolean;
|
|
4
|
+
export interface PageForms {
|
|
5
|
+
enquiryForm: boolean;
|
|
6
|
+
newsletterForm: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function detectPageForms($: CheerioAPI, pageUrl: string): PageForms;
|
|
2
9
|
export declare function extractPublicContact(html: string, finalUrl: string): PublicContact;
|
package/dist/contact.js
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { load } from "cheerio";
|
|
2
2
|
const emailPattern = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi;
|
|
3
|
-
|
|
3
|
+
// Contact extraction keeps its narrow patterns because a contact page link raises contact confidence and picks the
|
|
4
|
+
// outreach channel; the broader link patterns below only decide whether a visitor can reach the business.
|
|
5
|
+
const contactPagePathPattern = /(?:^|\/)(contact|contact-us|iletisim|reach-us|booking|appointment)(?:\/|$)/i;
|
|
6
|
+
const contactPageTextPattern = /contact|iletisim|appointment|booking/i;
|
|
7
|
+
const contactPathPattern = /(?:^|\/)(contact|contact-us|get-in-touch|enquir(?:e|y|ies)|iletisim|reach-us|book|booking|appointments?)(?:\.[a-z]+)?(?:\/|$)/i;
|
|
8
|
+
const contactTextPattern = /contact|get in touch|enquir|iletisim|iletişim|appointment|\bbook(?:ings?)?\b/i;
|
|
9
|
+
const bookingPathPattern = /(?:^|[/._-])(book|booking|bookings|appointments?|reserve|reservations?)(?:[/._-]|$)/i;
|
|
10
|
+
const bookingTextPattern = /\b(?:book(?:ings?)?|appointments?|reserve|reservations?)\b/i;
|
|
11
|
+
const bookingHostPattern = /dentally|setmore|calendly|fresha|treatwell|booksy|simplybook|acuityscheduling|mindbody|resdiary|opentable|zocdoc|vagaro|gettimely|phorest|youcanbook/i;
|
|
12
|
+
const embeddedFormPattern = /forms\.gle|docs\.google\.com\/forms|typeform\.com|jotform|formstack|hsforms|wufoo|cognitoforms|tally\.so/i;
|
|
13
|
+
const textInputTypes = new Set(["", "text", "email", "tel"]);
|
|
14
|
+
const ignoredInputTypes = new Set(["hidden", "submit", "button", "reset", "image", "checkbox", "radio"]);
|
|
15
|
+
const enquiryFieldPattern = /name|phone|e-?mail|message/i;
|
|
16
|
+
const newsletterCuePattern = /newsletter|subscri|mailchimp|list-manage/i;
|
|
4
17
|
const socialHosts = ["facebook.com", "instagram.com", "linkedin.com", "x.com", "twitter.com", "tiktok.com", "youtube.com"];
|
|
5
18
|
const placeholderSocialPattern = /\/(yourbusiness|example|placeholder|your-company|yourcompany)(?:\/?$)/i;
|
|
6
19
|
function unique(values) {
|
|
@@ -55,6 +68,96 @@ function isPlaceholderSocial(url) {
|
|
|
55
68
|
return true;
|
|
56
69
|
}
|
|
57
70
|
}
|
|
71
|
+
function isContactLink(url, text) {
|
|
72
|
+
return contactPathPattern.test(new URL(url).pathname) || contactTextPattern.test(text);
|
|
73
|
+
}
|
|
74
|
+
function siteHost(url) {
|
|
75
|
+
return new URL(url).hostname.replace(/^www\./, "").toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
function isBookingLink(url, text) {
|
|
78
|
+
const parsed = new URL(url);
|
|
79
|
+
return bookingHostPattern.test(parsed.hostname) || bookingPathPattern.test(parsed.pathname) || bookingTextPattern.test(text);
|
|
80
|
+
}
|
|
81
|
+
// Links to another page of the same site (or a subdomain) that look like a contact or booking page, or
|
|
82
|
+
// off-site links to a booking page. An off-site link that only says "contact" (such as a web agency footer) does not count.
|
|
83
|
+
// Anchors back to the audited page itself are skipped: that page's own forms and email links are checked directly.
|
|
84
|
+
export function hasContactOrBookingLink($, pageUrl) {
|
|
85
|
+
const page = normalizeUrl(pageUrl, pageUrl);
|
|
86
|
+
if (!page) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const host = siteHost(page);
|
|
90
|
+
return $("a[href]")
|
|
91
|
+
.toArray()
|
|
92
|
+
.some((element) => {
|
|
93
|
+
const url = normalizeUrl($(element).attr("href")?.trim() ?? "", page);
|
|
94
|
+
if (!url || url === page) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const linkHost = siteHost(url);
|
|
98
|
+
const text = $(element).text().trim();
|
|
99
|
+
return linkHost === host || linkHost.endsWith(`.${host}`) ? isContactLink(url, text) : isBookingLink(url, text);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// An enquiry form has a message box, or at least two text-like fields that look like contact details.
|
|
103
|
+
// Search forms and newsletter signups are not enquiry forms; embedded form providers count as one.
|
|
104
|
+
export function detectPageForms($, pageUrl) {
|
|
105
|
+
let enquiryForm = false;
|
|
106
|
+
let newsletterForm = false;
|
|
107
|
+
for (const form of $("form").toArray()) {
|
|
108
|
+
const $form = $(form);
|
|
109
|
+
const fields = $form
|
|
110
|
+
.find("input")
|
|
111
|
+
.toArray()
|
|
112
|
+
.map((input) => ({
|
|
113
|
+
type: ($(input).attr("type") ?? "").trim().toLowerCase(),
|
|
114
|
+
name: $(input).attr("name") ?? "",
|
|
115
|
+
label: `${$(input).attr("name") ?? ""} ${$(input).attr("id") ?? ""}`
|
|
116
|
+
}))
|
|
117
|
+
.filter((input) => !ignoredInputTypes.has(input.type));
|
|
118
|
+
const textFields = fields.filter((input) => textInputTypes.has(input.type));
|
|
119
|
+
// reCAPTCHA/hCaptcha inject a hidden response textarea into rendered pages; it is not a message box.
|
|
120
|
+
const hasTextarea = $form.find("textarea").not('[name*="captcha"], [id*="captcha"]').length > 0;
|
|
121
|
+
const isEmail = (input) => input.type === "email" || /e-?mail/i.test(input.label);
|
|
122
|
+
const isSearch = $form.closest('[role="search"]').length > 0 ||
|
|
123
|
+
/search/i.test($form.attr("action") ?? "") ||
|
|
124
|
+
(fields.length === 1 && (fields[0].type === "search" || /^(q|s|search)$/i.test(fields[0].name)));
|
|
125
|
+
if (isSearch) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const newsletterCue = [
|
|
129
|
+
$form.attr("action"),
|
|
130
|
+
$form.attr("id"),
|
|
131
|
+
$form.attr("class"),
|
|
132
|
+
...$form
|
|
133
|
+
.find('button, input[type="submit"]')
|
|
134
|
+
.toArray()
|
|
135
|
+
.map((button) => `${$(button).text()} ${$(button).attr("value") ?? ""}`)
|
|
136
|
+
].join(" ");
|
|
137
|
+
const isNewsletter = !hasTextarea &&
|
|
138
|
+
((fields.length === 1 && isEmail(fields[0])) || (newsletterCuePattern.test(newsletterCue) && textFields.some(isEmail)));
|
|
139
|
+
if (isNewsletter) {
|
|
140
|
+
newsletterForm = true;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (hasTextarea ||
|
|
144
|
+
(textFields.length >= 2 &&
|
|
145
|
+
textFields.some((input) => input.type === "email" || input.type === "tel" || enquiryFieldPattern.test(input.label)))) {
|
|
146
|
+
enquiryForm = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const embeddedForm = $("iframe[src], script[src]")
|
|
150
|
+
.toArray()
|
|
151
|
+
.some((element) => {
|
|
152
|
+
const src = normalizeUrl($(element).attr("src")?.trim() ?? "", pageUrl);
|
|
153
|
+
if (!src) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const url = new URL(src);
|
|
157
|
+
return embeddedFormPattern.test(`${url.hostname}${url.pathname}`);
|
|
158
|
+
});
|
|
159
|
+
return { enquiryForm: enquiryForm || embeddedForm, newsletterForm };
|
|
160
|
+
}
|
|
58
161
|
function confidenceFor(contact, sourceCount) {
|
|
59
162
|
if (sourceCount >= 3 || (contact.publicEmail && contact.publicPhone)) {
|
|
60
163
|
return "High";
|
|
@@ -108,7 +211,7 @@ export function extractPublicContact(html, finalUrl) {
|
|
|
108
211
|
continue;
|
|
109
212
|
}
|
|
110
213
|
const text = $(element).text().trim();
|
|
111
|
-
if (
|
|
214
|
+
if (contactPagePathPattern.test(new URL(url).pathname) || contactPageTextPattern.test(text)) {
|
|
112
215
|
contactPageUrls.push(url);
|
|
113
216
|
sources.push("contact-page");
|
|
114
217
|
}
|
|
@@ -125,6 +228,7 @@ export function extractPublicContact(html, finalUrl) {
|
|
|
125
228
|
publicPhone: unique(phones)[0],
|
|
126
229
|
whatsappUrl: unique(whatsappUrls)[0],
|
|
127
230
|
contactPageUrl: unique(contactPageUrls)[0],
|
|
231
|
+
contactFormUrl: detectPageForms($, finalUrl).enquiryForm ? finalUrl : undefined,
|
|
128
232
|
socialProfiles: unique(socialProfiles)
|
|
129
233
|
};
|
|
130
234
|
const uniqueSources = unique(sources);
|
package/dist/contact.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact.js","sourceRoot":"","sources":["../src/contact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"contact.js","sourceRoot":"","sources":["../src/contact.ts"],"names":[],"mappings":"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"}
|
package/dist/discovery.d.ts
CHANGED
package/dist/discovery.js
CHANGED
|
@@ -802,18 +802,101 @@ function areaCodeMismatches(inputs) {
|
|
|
802
802
|
}
|
|
803
803
|
return mismatches;
|
|
804
804
|
}
|
|
805
|
+
const publicSectorDomains = ["nhs.uk", "gov.uk", "gov", "police.uk", "ac.uk", "sch.uk"];
|
|
806
|
+
// Social, link-in-bio, directory, site-builder, and booking hosts give each business its own page on a shared host,
|
|
807
|
+
// so sharing the host or having a deep path says nothing about being a chain. Such leads usually lack a real website.
|
|
808
|
+
const hostedPageDomains = [
|
|
809
|
+
...sharedProfileHostnames,
|
|
810
|
+
"facebook.com",
|
|
811
|
+
"instagram.com",
|
|
812
|
+
"linkedin.com",
|
|
813
|
+
"x.com",
|
|
814
|
+
"twitter.com",
|
|
815
|
+
"tiktok.com",
|
|
816
|
+
"youtube.com",
|
|
817
|
+
"sites.google.com",
|
|
818
|
+
"google.com",
|
|
819
|
+
"yell.com",
|
|
820
|
+
"tripadvisor.com",
|
|
821
|
+
"tripadvisor.co.uk",
|
|
822
|
+
"booking.com",
|
|
823
|
+
"treatwell.co.uk",
|
|
824
|
+
"fresha.com",
|
|
825
|
+
"booksy.com",
|
|
826
|
+
"setmore.com",
|
|
827
|
+
"calendly.com",
|
|
828
|
+
"opentable.com",
|
|
829
|
+
"opentable.co.uk",
|
|
830
|
+
"resdiary.com"
|
|
831
|
+
];
|
|
832
|
+
function isHostedPage(host) {
|
|
833
|
+
return hostedPageDomains.some((domain) => host === domain || host.endsWith(`.${domain}`));
|
|
834
|
+
}
|
|
835
|
+
function websiteUrlOf(input) {
|
|
836
|
+
if (!input.resolution.hasWebsite || !input.resolution.websiteUrl)
|
|
837
|
+
return undefined;
|
|
838
|
+
try {
|
|
839
|
+
return new URL(input.resolution.websiteUrl);
|
|
840
|
+
}
|
|
841
|
+
catch {
|
|
842
|
+
return undefined;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
// Chain branches and public bodies rarely buy small-business website work. The strongest signal wins: a
|
|
846
|
+
// public-sector domain, then one website host shared by several leads in this search, then a deep branch page.
|
|
847
|
+
function chainReasons(inputs) {
|
|
848
|
+
const leads = inputs.flatMap((input) => {
|
|
849
|
+
const url = websiteUrlOf(input);
|
|
850
|
+
return url ? [{ input, url, host: url.hostname.toLowerCase().replace(/^www\./, "") }] : [];
|
|
851
|
+
});
|
|
852
|
+
// Count distinct business names over distinct leads per host, so one record listed twice or two source records
|
|
853
|
+
// for the same business do not look like a chain.
|
|
854
|
+
const namesByHost = new Map();
|
|
855
|
+
for (const { input, host } of leads) {
|
|
856
|
+
const key = stableLeadKey(input);
|
|
857
|
+
const names = namesByHost.get(host) ?? new Map();
|
|
858
|
+
if (!names.has(key))
|
|
859
|
+
names.set(key, normalizeLabel(input.candidate.label) ?? key);
|
|
860
|
+
namesByHost.set(host, names);
|
|
861
|
+
}
|
|
862
|
+
const reasons = new Map();
|
|
863
|
+
for (const { input, url, host } of leads) {
|
|
864
|
+
const publicDomain = publicSectorDomains.find((domain) => host === domain || host.endsWith(`.${domain}`));
|
|
865
|
+
const hosted = isHostedPage(host);
|
|
866
|
+
const sharedCount = hosted ? 0 : new Set(namesByHost.get(host)?.values()).size;
|
|
867
|
+
const segments = url.pathname.split("/").filter(Boolean);
|
|
868
|
+
if (/^[a-z]{2}(-[a-z]{2})?$/i.test(segments[0] ?? ""))
|
|
869
|
+
segments.shift();
|
|
870
|
+
if (/^index\.(html|php)$/i.test(segments.at(-1) ?? ""))
|
|
871
|
+
segments.pop();
|
|
872
|
+
const reason = publicDomain
|
|
873
|
+
? `Website is on a public-sector domain (${publicDomain}); this is not a small-business lead`
|
|
874
|
+
: sharedCount >= 2
|
|
875
|
+
? `${sharedCount} leads in this search share ${host}; this looks like a multi-location brand`
|
|
876
|
+
: !hosted && segments.length >= 2
|
|
877
|
+
? `Website URL is a branch page on a larger site (/${segments[0]}/…)`
|
|
878
|
+
: undefined;
|
|
879
|
+
if (reason)
|
|
880
|
+
reasons.set(input, reason);
|
|
881
|
+
}
|
|
882
|
+
return reasons;
|
|
883
|
+
}
|
|
805
884
|
export function buildProspectRows(inputs) {
|
|
806
885
|
const locationMismatches = areaCodeMismatches(inputs);
|
|
886
|
+
const chains = chainReasons(inputs);
|
|
807
887
|
return inputs.map((input) => {
|
|
808
888
|
const locationMismatch = locationMismatches.get(input);
|
|
889
|
+
const chainReason = chains.get(input);
|
|
809
890
|
if (input.audit?.identity?.status === "conflict") {
|
|
810
891
|
input = { ...input, audit: { ...input.audit, status: "failed", contact: undefined, dotnetStack: undefined, score: undefined, topFinding: undefined, reportPath: undefined, error: input.audit.error ?? "Website identity conflicts with the source; manual review is required." } };
|
|
811
892
|
}
|
|
812
893
|
const audit = input.audit ?? { status: "not-audited" };
|
|
813
894
|
const basePriority = priorityFor(input);
|
|
814
|
-
const priority =
|
|
815
|
-
? { priority:
|
|
816
|
-
:
|
|
895
|
+
const priority = chainReason
|
|
896
|
+
? { priority: "low", nextAction: "Skip unless you are targeting the head office; this lead looks like a chain branch or public body." }
|
|
897
|
+
: locationMismatch
|
|
898
|
+
? { priority: basePriority.priority === "low" ? "low" : "medium", nextAction: "Confirm the business location before outreach; its phone area code does not match this search." }
|
|
899
|
+
: basePriority;
|
|
817
900
|
const enrichment = enrichmentFor(input);
|
|
818
901
|
const handoff = contactHandoffFor(input);
|
|
819
902
|
const contact = prospectContact(input);
|
|
@@ -831,8 +914,8 @@ export function buildProspectRows(inputs) {
|
|
|
831
914
|
auditStatus: audit.status,
|
|
832
915
|
score: audit.score,
|
|
833
916
|
topFinding: audit.topFinding,
|
|
834
|
-
opportunityScore: opportunityScoreFor(input),
|
|
835
|
-
opportunityReasons:
|
|
917
|
+
opportunityScore: chainReason ? Math.min(opportunityScoreFor(input), 20) : opportunityScoreFor(input),
|
|
918
|
+
opportunityReasons: [...opportunityReasonsFor(input), ...[locationMismatch, chainReason].filter((reason) => reason !== undefined)],
|
|
836
919
|
...enrichment,
|
|
837
920
|
...details,
|
|
838
921
|
...(input.candidate.source === "overture" ? {
|
|
@@ -856,7 +939,8 @@ export function buildProspectRows(inputs) {
|
|
|
856
939
|
reportPath: audit.reportPath,
|
|
857
940
|
error: audit.error ?? input.resolution.reason,
|
|
858
941
|
dotnetStack: audit.dotnetStack?.stack,
|
|
859
|
-
dotnetLegacyFramework: audit.dotnetStack?.legacyFramework
|
|
942
|
+
dotnetLegacyFramework: audit.dotnetStack?.legacyFramework,
|
|
943
|
+
chainReason
|
|
860
944
|
};
|
|
861
945
|
});
|
|
862
946
|
}
|
|
@@ -980,6 +1064,7 @@ export function renderProspectRowsCsv(rows, preset = "standard") {
|
|
|
980
1064
|
"error",
|
|
981
1065
|
"dotnetStack",
|
|
982
1066
|
"dotnetLegacyFramework",
|
|
1067
|
+
"chainReason",
|
|
983
1068
|
...detailColumns
|
|
984
1069
|
];
|
|
985
1070
|
const body = rows.map((row) => [
|
|
@@ -1019,6 +1104,7 @@ export function renderProspectRowsCsv(rows, preset = "standard") {
|
|
|
1019
1104
|
row.error ?? "",
|
|
1020
1105
|
row.dotnetStack ?? "",
|
|
1021
1106
|
row.dotnetLegacyFramework === undefined ? "" : row.dotnetLegacyFramework ? "yes" : "no",
|
|
1107
|
+
row.chainReason ?? "",
|
|
1022
1108
|
...detailColumns.map((key) => key === "sourceProvenance" || key === "identityReasons" || key === "identityEvidence" ? JSON.stringify(row[key] ?? []) : String(row[key] ?? ""))
|
|
1023
1109
|
]
|
|
1024
1110
|
.map(escapeCsvCell)
|