open-local-audit 0.60.0 → 0.62.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.
@@ -0,0 +1,403 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { lstat, mkdir, mkdtemp, realpath, rename, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
4
+ import { runDiscovery } from "./discovery-runner.js";
5
+ import { packageReport } from "./report-pack.js";
6
+ import { summarizeReviewCsvFile } from "./review.js";
7
+ import { runShortlistReport } from "./shortlist-runner.js";
8
+ import { resolveGoogleMapsApiKey } from "./secrets.js";
9
+ import { readWorkflowConfig } from "./workflow-config.js";
10
+ export class WorkflowRunError extends Error {
11
+ summary;
12
+ constructor(summary) {
13
+ super(summary.error ? `Workflow failed during ${summary.error.stage}: ${summary.error.message}` : "Workflow failed");
14
+ this.name = "WorkflowRunError";
15
+ this.summary = summary;
16
+ }
17
+ }
18
+ const defaultDependencies = {
19
+ readWorkflowConfig,
20
+ runDiscovery,
21
+ runShortlistReport,
22
+ summarizeReviewCsvFile,
23
+ packageReport,
24
+ resolveGoogleMapsApiKey
25
+ };
26
+ const packageReportFileNames = [
27
+ "open-local-audit-report.json",
28
+ "open-local-audit-report.md",
29
+ "open-local-audit-report.html",
30
+ "open-local-audit-report.pdf"
31
+ ];
32
+ function slugify(value) {
33
+ return value
34
+ .normalize("NFKD")
35
+ .replace(/[\u0300-\u036f]/g, "")
36
+ .replace(/[^A-Za-z0-9]+/g, "-")
37
+ .replace(/^-+|-+$/g, "")
38
+ .toLowerCase();
39
+ }
40
+ function slugSourceFromLeadKey(leadKey) {
41
+ const trimmed = leadKey.trim();
42
+ if (!trimmed) {
43
+ return "";
44
+ }
45
+ if (trimmed.startsWith("url:")) {
46
+ const rawUrl = trimmed.slice(4);
47
+ try {
48
+ const parsed = new URL(rawUrl);
49
+ return `${parsed.hostname}${parsed.pathname}`.replace(/^www\./i, "");
50
+ }
51
+ catch {
52
+ return rawUrl;
53
+ }
54
+ }
55
+ return trimmed.replace(/^[a-z]+:/i, "");
56
+ }
57
+ export function safeLeadSlug(leadKey, companyName) {
58
+ const companySlug = slugify(companyName.trim());
59
+ if (companySlug) {
60
+ return companySlug;
61
+ }
62
+ const leadSlug = slugify(slugSourceFromLeadKey(leadKey));
63
+ return leadSlug || "lead";
64
+ }
65
+ function sanitizeErrorMessage(error, knownSecrets = []) {
66
+ if (error instanceof Error) {
67
+ const message = error.message.trim();
68
+ return knownSecrets
69
+ .filter((secret) => secret.length > 0)
70
+ .reduce((sanitized, secret) => sanitized.split(secret).join("[REDACTED]"), message || "Unknown error");
71
+ }
72
+ return "Unknown error";
73
+ }
74
+ function createInitialSummary(config) {
75
+ return {
76
+ version: 1,
77
+ status: "success",
78
+ stages: {
79
+ discovery: { status: "not-run" },
80
+ shortlist: { status: "not-run" },
81
+ review: { status: config.review ? "not-run" : "skipped" },
82
+ packaging: { status: config.packageReports ? "not-run" : "skipped" }
83
+ },
84
+ outputs: config.paths,
85
+ discoveredLeads: 0,
86
+ selectedLeads: 0,
87
+ packages: {
88
+ packaged: 0,
89
+ skipped: 0,
90
+ failed: 0,
91
+ entries: []
92
+ }
93
+ };
94
+ }
95
+ async function writePrettyJson(path, value) {
96
+ await mkdir(dirname(path), { recursive: true });
97
+ await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
98
+ }
99
+ async function writeWorkflowSummary(summary) {
100
+ await writePrettyJson(summary.outputs.workflowSummaryJson, summary);
101
+ }
102
+ async function throwPersistedWorkflowFailure(summary) {
103
+ try {
104
+ await writeWorkflowSummary(summary);
105
+ }
106
+ catch {
107
+ // The workflow failure remains authoritative if its summary cannot be persisted.
108
+ }
109
+ throw new WorkflowRunError(summary);
110
+ }
111
+ async function throwStageFailure(summary, stage, error, knownSecrets) {
112
+ markStageFailure(summary, stage, sanitizeErrorMessage(error, knownSecrets));
113
+ return throwPersistedWorkflowFailure(summary);
114
+ }
115
+ function markStageFailure(summary, stage, message) {
116
+ summary.status = "failed";
117
+ summary.stages[stage].status = "failed";
118
+ summary.error = {
119
+ stage,
120
+ message
121
+ };
122
+ }
123
+ async function prepareManagedDirectories(config) {
124
+ await mkdir(config.outDir, { recursive: true });
125
+ const outputInfo = await lstat(config.outDir);
126
+ if (outputInfo.isSymbolicLink()) {
127
+ throw new Error("Managed output directory must not be linked");
128
+ }
129
+ const realOutDir = await realpath(config.outDir);
130
+ const directories = [
131
+ { label: "reports", path: config.paths.reportsDir },
132
+ ...(config.packageReports ? [{ label: "packages", path: config.paths.packagesDir }] : [])
133
+ ];
134
+ for (const directory of directories) {
135
+ await mkdir(directory.path, { recursive: true });
136
+ const directoryInfo = await lstat(directory.path);
137
+ if (directoryInfo.isSymbolicLink()) {
138
+ throw new Error(`Managed ${directory.label} directory must not be linked`);
139
+ }
140
+ const realDirectory = await realpath(directory.path);
141
+ const relativeDirectory = relative(realOutDir, realDirectory);
142
+ if (relativeDirectory.startsWith("..") || isAbsolute(relativeDirectory)) {
143
+ throw new Error(`Managed ${directory.label} directory escapes output directory`);
144
+ }
145
+ }
146
+ }
147
+ async function resolvePackageInputDir(reportsDir, reportPath) {
148
+ const resolvedReportPath = resolve(reportsDir, reportPath);
149
+ const relativePath = relative(reportsDir, resolvedReportPath);
150
+ if (!relativePath || relativePath.startsWith("..") || isAbsolute(relativePath)) {
151
+ throw new Error("Report path escapes reports directory");
152
+ }
153
+ const inputDir = dirname(resolvedReportPath);
154
+ const [realReportsDir, realInputDir] = await Promise.all([realpath(reportsDir), realpath(inputDir)]);
155
+ const realRelativePath = relative(realReportsDir, realInputDir);
156
+ if (realRelativePath.startsWith("..") || isAbsolute(realRelativePath)) {
157
+ throw new Error("Report path escapes reports directory");
158
+ }
159
+ return { inputDir, realInputDir };
160
+ }
161
+ async function validatePackageSourceFiles(inputDir, realInputDir) {
162
+ for (const fileName of packageReportFileNames) {
163
+ const sourcePath = join(inputDir, fileName);
164
+ try {
165
+ const sourceInfo = await lstat(sourcePath);
166
+ if (sourceInfo.isSymbolicLink()) {
167
+ throw new Error("Linked report files are not allowed");
168
+ }
169
+ const realSourcePath = await realpath(sourcePath);
170
+ const relativeSourcePath = relative(realInputDir, realSourcePath);
171
+ if (relativeSourcePath.startsWith("..") || isAbsolute(relativeSourcePath)) {
172
+ throw new Error("Report file escapes input directory");
173
+ }
174
+ }
175
+ catch (error) {
176
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
177
+ continue;
178
+ }
179
+ throw error;
180
+ }
181
+ }
182
+ }
183
+ async function promotePackage(tempDir, finalDir) {
184
+ const backupDir = `${finalDir}.backup-${randomUUID()}`;
185
+ let hasBackup = false;
186
+ let promoted = false;
187
+ try {
188
+ await rename(finalDir, backupDir);
189
+ hasBackup = true;
190
+ }
191
+ catch (error) {
192
+ if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
193
+ throw error;
194
+ }
195
+ }
196
+ try {
197
+ await rename(tempDir, finalDir);
198
+ promoted = true;
199
+ if (hasBackup) {
200
+ await rm(backupDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
201
+ }
202
+ }
203
+ catch (error) {
204
+ if (hasBackup) {
205
+ try {
206
+ if (promoted) {
207
+ await rename(finalDir, tempDir);
208
+ }
209
+ await rename(backupDir, finalDir);
210
+ }
211
+ catch {
212
+ // Best-effort rollback; the original promotion error remains authoritative.
213
+ }
214
+ }
215
+ throw error;
216
+ }
217
+ }
218
+ function updateDiscoveryStage(summary, result) {
219
+ summary.stages.discovery = {
220
+ status: "success",
221
+ totalCandidates: result.summary.totalCandidates,
222
+ suppressedCandidates: result.summary.suppressedCandidates,
223
+ audited: result.summary.audited
224
+ };
225
+ summary.discoveredLeads = result.rows.length;
226
+ }
227
+ function updateShortlistStage(summary, result) {
228
+ summary.stages.shortlist = {
229
+ status: "success",
230
+ totalRows: result.totalRows,
231
+ suppressedRows: result.suppressedRows,
232
+ filteredRows: result.filteredRows,
233
+ selected: result.selected
234
+ };
235
+ summary.selectedLeads = result.selected;
236
+ }
237
+ function updateReviewStage(summary, result) {
238
+ summary.stages.review = {
239
+ status: "success",
240
+ totalRows: result.totalRows,
241
+ reviewedRows: result.reviewedRows,
242
+ actionableLeads: result.actionableLeadKeys.length,
243
+ staleRows: result.staleRows,
244
+ invalidReviewedAtRows: result.invalidReviewedAtRows,
245
+ unreviewedRows: result.unreviewedRows
246
+ };
247
+ }
248
+ function updatePackagingStage(summary) {
249
+ summary.stages.packaging = {
250
+ status: summary.packages.failed > 0 ? "failed" : "success",
251
+ packaged: summary.packages.packaged,
252
+ skipped: summary.packages.skipped,
253
+ failed: summary.packages.failed
254
+ };
255
+ }
256
+ function nextUniqueSlug(baseSlug, counts) {
257
+ const nextCount = (counts.get(baseSlug) ?? 0) + 1;
258
+ counts.set(baseSlug, nextCount);
259
+ return nextCount === 1 ? baseSlug : `${baseSlug}-${nextCount}`;
260
+ }
261
+ export async function runWorkflow(configPath, dependencies = {}) {
262
+ const resolvedDependencies = {
263
+ ...defaultDependencies,
264
+ ...dependencies
265
+ };
266
+ const config = await resolvedDependencies.readWorkflowConfig(configPath);
267
+ return await runResolvedWorkflow(config, resolvedDependencies);
268
+ }
269
+ export async function runResolvedWorkflow(config, dependencies = {}) {
270
+ const resolvedDependencies = {
271
+ ...defaultDependencies,
272
+ ...dependencies
273
+ };
274
+ await prepareManagedDirectories(config);
275
+ const summary = createInitialSummary(config);
276
+ const knownSecrets = [];
277
+ try {
278
+ const googleApiKey = config.discovery.provider === "google-places" ? resolvedDependencies.resolveGoogleMapsApiKey() : undefined;
279
+ if (googleApiKey) {
280
+ knownSecrets.push(googleApiKey);
281
+ }
282
+ const discoveryResult = await resolvedDependencies.runDiscovery({
283
+ provider: config.discovery.provider,
284
+ ...(config.discovery.provider === "manual-csv" ? { input: config.discovery.input } : {}),
285
+ ...(config.discovery.provider === "google-places" ? { query: config.discovery.query } : {}),
286
+ profile: config.discovery.profile,
287
+ outDir: config.paths.reportsDir,
288
+ exportCsv: config.paths.leadsCsv,
289
+ summaryJson: config.paths.discoverySummaryJson,
290
+ reviewCsv: config.review?.csv,
291
+ dryRun: false,
292
+ concurrency: config.discovery.concurrency,
293
+ ...(config.discovery.maxAudits !== undefined ? { maxAudits: config.discovery.maxAudits } : {}),
294
+ ...(config.discovery.provider === "google-places" ? { limit: config.discovery.limit } : {}),
295
+ ...(googleApiKey !== undefined ? { apiKey: googleApiKey } : {})
296
+ });
297
+ updateDiscoveryStage(summary, discoveryResult);
298
+ const shortlistResult = await resolvedDependencies.runShortlistReport({
299
+ input: config.paths.leadsCsv,
300
+ out: config.paths.shortlistCsv,
301
+ summaryJson: config.paths.shortlistSummaryJson,
302
+ reviewCsv: config.review?.csv,
303
+ format: "csv",
304
+ shortlist: config.shortlist
305
+ });
306
+ updateShortlistStage(summary, shortlistResult);
307
+ if (config.review) {
308
+ const reviewSummary = await resolvedDependencies.summarizeReviewCsvFile(config.review.csv, {
309
+ staleBefore: config.review.staleBefore
310
+ });
311
+ await writePrettyJson(config.paths.reviewSummaryJson, reviewSummary);
312
+ updateReviewStage(summary, reviewSummary);
313
+ }
314
+ if (config.packageReports) {
315
+ const slugCounts = new Map();
316
+ for (const lead of shortlistResult.leads) {
317
+ const packageEntry = await packageLead(config.paths, lead, slugCounts, resolvedDependencies.packageReport, knownSecrets);
318
+ summary.packages.entries.push(packageEntry);
319
+ if (packageEntry.status === "packaged") {
320
+ summary.packages.packaged += 1;
321
+ }
322
+ else if (packageEntry.status === "skipped") {
323
+ summary.packages.skipped += 1;
324
+ }
325
+ else {
326
+ summary.packages.failed += 1;
327
+ }
328
+ }
329
+ updatePackagingStage(summary);
330
+ if (summary.packages.failed > 0) {
331
+ summary.status = "failed";
332
+ summary.error = {
333
+ stage: "packaging",
334
+ message: `${summary.packages.failed} package ${summary.packages.failed === 1 ? "entry" : "entries"} failed`
335
+ };
336
+ await throwPersistedWorkflowFailure(summary);
337
+ }
338
+ }
339
+ }
340
+ catch (error) {
341
+ if (error instanceof WorkflowRunError) {
342
+ throw error;
343
+ }
344
+ const failedStage = summary.stages.discovery.status !== "success"
345
+ ? "discovery"
346
+ : summary.stages.shortlist.status !== "success"
347
+ ? "shortlist"
348
+ : summary.stages.review.status === "not-run"
349
+ ? "review"
350
+ : "packaging";
351
+ await throwStageFailure(summary, failedStage, error, knownSecrets);
352
+ }
353
+ await writeWorkflowSummary(summary);
354
+ return summary;
355
+ }
356
+ async function packageLead(paths, lead, slugCounts, packageReportDependency, knownSecrets) {
357
+ const reportPath = lead.reportPath.trim();
358
+ if (!reportPath) {
359
+ return {
360
+ leadKey: lead.leadKey,
361
+ companyName: lead.companyName,
362
+ status: "skipped"
363
+ };
364
+ }
365
+ const slug = nextUniqueSlug(safeLeadSlug(lead.leadKey, lead.companyName), slugCounts);
366
+ const outDir = join(paths.packagesDir, slug);
367
+ let tempDir;
368
+ try {
369
+ const { inputDir, realInputDir } = await resolvePackageInputDir(paths.reportsDir, reportPath);
370
+ await validatePackageSourceFiles(inputDir, realInputDir);
371
+ await mkdir(paths.packagesDir, { recursive: true });
372
+ tempDir = await mkdtemp(join(paths.packagesDir, `.${slug}-tmp-`));
373
+ await packageReportDependency({
374
+ inputDir,
375
+ outDir: tempDir
376
+ });
377
+ await promotePackage(tempDir, outDir);
378
+ tempDir = undefined;
379
+ return {
380
+ leadKey: lead.leadKey,
381
+ companyName: lead.companyName,
382
+ status: "packaged",
383
+ outDir
384
+ };
385
+ }
386
+ catch (error) {
387
+ if (tempDir) {
388
+ try {
389
+ await rm(tempDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
390
+ }
391
+ catch {
392
+ // Keep the package failure useful even if temporary output cannot be removed.
393
+ }
394
+ }
395
+ return {
396
+ leadKey: lead.leadKey,
397
+ companyName: lead.companyName,
398
+ status: "failed",
399
+ error: sanitizeErrorMessage(error, knownSecrets)
400
+ };
401
+ }
402
+ }
403
+ //# sourceMappingURL=workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-local-audit",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "description": "Open-source website and local presence auditor for small businesses.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  "cheerio": "^1.2.0",
50
50
  "chrome-launcher": "^1.2.1",
51
51
  "commander": "^12.1.0",
52
- "lighthouse": "12.6.1",
52
+ "lighthouse": "12.6.1",
53
53
  "pdfkit": "^0.18.0",
54
54
  "zod": "^3.24.1"
55
55
  },
@@ -58,6 +58,6 @@
58
58
  "@types/pdfkit": "^0.17.6",
59
59
  "tsx": "^4.22.4",
60
60
  "typescript": "^5.7.2",
61
- "vitest": "^4.1.5"
62
- }
63
- }
61
+ "vitest": "^4.1.5"
62
+ }
63
+ }