@cleaver/breakcheck-core 0.2.5 → 0.3.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/README.md +94 -0
- package/dist/api/index.d.ts +23 -5
- package/dist/api/index.js +71 -10
- package/dist/api/index.js.map +1 -1
- package/dist/core/check/index.d.ts +9 -0
- package/dist/core/check/index.js +116 -0
- package/dist/core/check/index.js.map +1 -0
- package/dist/core/compare/classes/ComparisonRepository.d.ts +11 -0
- package/dist/core/compare/classes/ComparisonRepository.js +26 -4
- package/dist/core/compare/classes/ComparisonRepository.js.map +1 -1
- package/dist/core/compare/index.js +20 -4
- package/dist/core/compare/index.js.map +1 -1
- package/dist/core/crawler/index.d.ts +7 -1
- package/dist/core/crawler/index.js +17 -2
- package/dist/core/crawler/index.js.map +1 -1
- package/dist/core/rules/RulesEngine.js.map +1 -1
- package/dist/core/snapshot/classes/SnapshotRepository.d.ts +15 -2
- package/dist/core/snapshot/classes/SnapshotRepository.js +110 -9
- package/dist/core/snapshot/classes/SnapshotRepository.js.map +1 -1
- package/dist/core/snapshot/index.d.ts +2 -1
- package/dist/core/snapshot/index.js +5 -2
- package/dist/core/snapshot/index.js.map +1 -1
- package/dist/core/snapshot/route-coverage.d.ts +3 -0
- package/dist/core/snapshot/route-coverage.js +18 -0
- package/dist/core/snapshot/route-coverage.js.map +1 -0
- package/dist/core/snapshot/update-routes.d.ts +4 -0
- package/dist/core/snapshot/update-routes.js +58 -0
- package/dist/core/snapshot/update-routes.js.map +1 -0
- package/dist/core/view/index.d.ts +2 -1
- package/dist/core/view/index.js +4 -4
- package/dist/core/view/index.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +18 -0
- package/dist/lib/config.js +363 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crawlee-logger.js.map +1 -1
- package/dist/lib/logger.d.ts +5 -4
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/root.d.ts +1 -1
- package/dist/lib/root.js +17 -6
- package/dist/lib/root.js.map +1 -1
- package/dist/lib/storage.d.ts +12 -0
- package/dist/lib/storage.js +76 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/types/api.d.ts +42 -0
- package/dist/types/compare.d.ts +5 -2
- package/dist/types/config.d.ts +72 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/rules.d.ts +8 -3
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -20,6 +20,63 @@ Node.js 22 or newer is required.
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## Project configuration and storage
|
|
24
|
+
|
|
25
|
+
The core package does not implicitly read `breakcheck.config.json`; library
|
|
26
|
+
callers choose configuration explicitly. `resolveProjectConfig` loads and
|
|
27
|
+
validates version-1 and version-2 JSON files, while `writeProjectConfig`
|
|
28
|
+
creates one with exclusive file creation:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import {
|
|
32
|
+
resolveProjectConfig,
|
|
33
|
+
writeProjectConfig,
|
|
34
|
+
} from "@cleaver/breakcheck-core";
|
|
35
|
+
|
|
36
|
+
const project = await resolveProjectConfig({
|
|
37
|
+
configPath: "./breakcheck.config.json",
|
|
38
|
+
});
|
|
39
|
+
await writeProjectConfig("./new-breakcheck.config.json", {
|
|
40
|
+
version: 1,
|
|
41
|
+
baseUrl: "https://example.com",
|
|
42
|
+
storageDir: ".breakcheck",
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Config paths resolve relative to the config file. `storageDir` is the artifact
|
|
47
|
+
root containing `snapshots/` and `comparisons`; Crawlee's temporary datasets
|
|
48
|
+
and queues are separate. An omitted storage option in the operational API
|
|
49
|
+
keeps the legacy `findRootDir()` behavior. To use another root, pass the same
|
|
50
|
+
`{ storageDir }` option to each operation:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
const storage = { storageDir: "/work/site/.breakcheck" };
|
|
54
|
+
await createSnapshotFromConfig(snapshotConfig, storage);
|
|
55
|
+
await listSnapshots(storage);
|
|
56
|
+
await runComparison(comparisonConfig, storage);
|
|
57
|
+
await startViewServer("v1-vs-v2-comparison", 8080, storage);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Changing the storage root does not migrate existing artifacts.
|
|
61
|
+
|
|
62
|
+
### Compiling a rules DSL
|
|
63
|
+
|
|
64
|
+
Use `compileRulesDsl` to parse and validate a directory containing
|
|
65
|
+
`rules.breakcheck`. It returns the intermediate `RulesDocument` shape used
|
|
66
|
+
by the rules engine; the runtime-only `Ruleset.name` metadata is not included.
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
import { compileRulesDsl } from "@cleaver/breakcheck-core";
|
|
70
|
+
|
|
71
|
+
const document = await compileRulesDsl("./my-rules");
|
|
72
|
+
console.log(JSON.stringify(document, null, 2));
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Relative directories resolve from `process.cwd()`. Syntax and engine
|
|
76
|
+
validation errors reject the promise before a document is returned.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
23
80
|
## API Usage
|
|
24
81
|
|
|
25
82
|
The `@cleaver/breakcheck-core` library exposes a set of simple, asynchronous functions to manage the entire workflow.
|
|
@@ -93,6 +150,43 @@ same-origin, and duplicates are removed in first-seen order. An invalid or
|
|
|
93
150
|
empty manifest fails before crawling. File and stdin reading are CLI concerns;
|
|
94
151
|
the core API receives the already-created array.
|
|
95
152
|
|
|
153
|
+
### Exact-route regression checks
|
|
154
|
+
|
|
155
|
+
`runSiteCheck` captures only the supplied routes, verifies crawl coverage, then
|
|
156
|
+
compares them with a stored baseline using the same comparison engine as
|
|
157
|
+
`runComparison`. Added or removed routes count as differences. The core API
|
|
158
|
+
does not start a site; the CLI handles preparation and server lifecycle. The
|
|
159
|
+
route list scopes page comparisons and added/removed route results, so snapshot
|
|
160
|
+
changes outside the manifest do not affect a route-scoped check.
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { runSiteCheck } from "@cleaver/breakcheck-core";
|
|
164
|
+
|
|
165
|
+
const result = await runSiteCheck(
|
|
166
|
+
{
|
|
167
|
+
baseUrl: "http://127.0.0.1:4000",
|
|
168
|
+
name: "check-local-run-1",
|
|
169
|
+
baselineSnapshotId: "site-baseline",
|
|
170
|
+
routes: ["/", "/about"],
|
|
171
|
+
crawlSettings: {
|
|
172
|
+
baseUrl: "http://127.0.0.1:4000",
|
|
173
|
+
crawlerType: "cheerio",
|
|
174
|
+
maxConcurrency: 5,
|
|
175
|
+
},
|
|
176
|
+
ruleset: "./rules",
|
|
177
|
+
},
|
|
178
|
+
{ storageDir: "./.breakcheck" },
|
|
179
|
+
);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The result status is `passed`, `differences`, or `failed`. The generated after
|
|
183
|
+
snapshot and detailed comparison remain in the configured storage directory.
|
|
184
|
+
`updateSnapshotRoutesFromConfig` is a separate API for explicitly replacing
|
|
185
|
+
selected baseline routes; it stages and validates the new pages before
|
|
186
|
+
committing them and preserves routes outside the selected list. Pass an
|
|
187
|
+
`AbortSignal` in `OperationOptions` to cancel an active crawl; baseline updates
|
|
188
|
+
check cancellation before replacing the stored routes.
|
|
189
|
+
|
|
96
190
|
### Configuring Logs
|
|
97
191
|
|
|
98
192
|
The core package uses pretty Pino logs by default. Call `configureLogger` before
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { logger } from "../lib/logger.js";
|
|
2
|
-
import type { ComparisonConfig, ComparisonSummary, SnapshotConfig, SnapshotResult } from "../types/api.js";
|
|
2
|
+
import type { ComparisonConfig, ComparisonSummary, SiteCheckConfig, SiteCheckResult, SnapshotRouteUpdateResult, SnapshotConfig, SnapshotResult, OperationOptions, StorageOptions } from "../types/api.js";
|
|
3
|
+
import type { RulesDocument } from "../types/rules.js";
|
|
3
4
|
/**
|
|
4
5
|
* Creates a snapshot of a website based on the provided configuration.
|
|
5
6
|
* Orchestrates calls to Crawler and Snapshot Manager.
|
|
6
7
|
*/
|
|
7
|
-
export declare function createSnapshotFromConfig(config: SnapshotConfig): Promise<SnapshotResult>;
|
|
8
|
+
export declare function createSnapshotFromConfig(config: SnapshotConfig, options?: OperationOptions): Promise<SnapshotResult>;
|
|
9
|
+
/** Runs one exact-route regression check against a stored baseline snapshot. */
|
|
10
|
+
export declare function runSiteCheck(config: SiteCheckConfig, options?: OperationOptions): Promise<SiteCheckResult>;
|
|
11
|
+
/** Crawls selected routes and atomically merges them into a stored baseline. */
|
|
12
|
+
export declare function updateSnapshotRoutesFromConfig(config: SnapshotConfig, baselineSnapshotId: string, options?: OperationOptions): Promise<SnapshotRouteUpdateResult>;
|
|
8
13
|
/**
|
|
9
14
|
* Starts a snapshot job and returns the job status.
|
|
10
15
|
*/
|
|
@@ -16,9 +21,22 @@ export declare function createSnapshotFromConfig(config: SnapshotConfig): Promis
|
|
|
16
21
|
* Orchestrates calls to Snapshot Manager, Rules Engine Parser (if needed),
|
|
17
22
|
* DOM Processor, and Diff Engine.
|
|
18
23
|
*/
|
|
19
|
-
export declare function runComparison(config: ComparisonConfig): Promise<ComparisonSummary>;
|
|
24
|
+
export declare function runComparison(config: ComparisonConfig, options?: StorageOptions): Promise<ComparisonSummary>;
|
|
25
|
+
/**
|
|
26
|
+
* Parses and validates a rules.breakcheck directory into the intermediate
|
|
27
|
+
* JSON document used by the rules engine.
|
|
28
|
+
*/
|
|
29
|
+
export declare function compileRulesDsl(rulesDirectory: string): Promise<RulesDocument>;
|
|
20
30
|
/**
|
|
21
31
|
* Lists all available snapshots with their details
|
|
22
32
|
*/
|
|
23
|
-
export declare function listSnapshots(): Promise<import("../index.js").SnapshotSummary[]>;
|
|
24
|
-
|
|
33
|
+
export declare function listSnapshots(options?: StorageOptions): Promise<import("../index.js").SnapshotSummary[]>;
|
|
34
|
+
/** Deletes one named snapshot. */
|
|
35
|
+
export declare function deleteSnapshot(name: string, options?: StorageOptions): Promise<boolean>;
|
|
36
|
+
/** Deletes all snapshots and returns the names that were removed. */
|
|
37
|
+
export declare function deleteAllSnapshots(options?: StorageOptions): Promise<string[]>;
|
|
38
|
+
/** Deletes one named comparison. */
|
|
39
|
+
export declare function deleteComparison(name: string, options?: StorageOptions): Promise<boolean>;
|
|
40
|
+
/** Deletes all comparisons and returns the names that were removed. */
|
|
41
|
+
export declare function deleteAllComparisons(options?: StorageOptions): Promise<string[]>;
|
|
42
|
+
export { logger, type ComparisonConfig, type OperationOptions, type SiteCheckConfig, type SiteCheckResult, type SnapshotRouteUpdateResult, type SnapshotConfig, type StorageOptions, };
|
package/dist/api/index.js
CHANGED
|
@@ -2,14 +2,37 @@ import { compareSnapshots } from "../core/compare/index.js";
|
|
|
2
2
|
import { ComparisonRepository } from "../core/compare/classes/ComparisonRepository.js";
|
|
3
3
|
import { RulesEngine } from "../core/rules/RulesEngine.js";
|
|
4
4
|
import { createSnapshot, SnapshotRepository } from "../core/snapshot/index.js";
|
|
5
|
+
import { runSiteCheck as runSiteCheckWorkflow } from "../core/check/index.js";
|
|
6
|
+
import { updateSnapshotRoutes } from "../core/snapshot/update-routes.js";
|
|
5
7
|
import { logger } from "../lib/logger.js";
|
|
8
|
+
import { resolveStorageContext } from "../lib/storage.js";
|
|
9
|
+
import { processRulesDsl } from "../core/rules/RulesDsl.js";
|
|
6
10
|
/**
|
|
7
11
|
* Creates a snapshot of a website based on the provided configuration.
|
|
8
12
|
* Orchestrates calls to Crawler and Snapshot Manager.
|
|
9
13
|
*/
|
|
10
|
-
export async function createSnapshotFromConfig(config) {
|
|
11
|
-
const
|
|
12
|
-
|
|
14
|
+
export async function createSnapshotFromConfig(config, options = {}) {
|
|
15
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
16
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
17
|
+
return createSnapshot(config, snapshotRepository, options.signal);
|
|
18
|
+
}
|
|
19
|
+
/** Runs one exact-route regression check against a stored baseline snapshot. */
|
|
20
|
+
export async function runSiteCheck(config, options = {}) {
|
|
21
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
22
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
23
|
+
return runSiteCheckWorkflow(config, {
|
|
24
|
+
snapshotRepository,
|
|
25
|
+
createSnapshot: (snapshotConfig, signal) => createSnapshot(snapshotConfig, snapshotRepository, signal),
|
|
26
|
+
runComparison: (comparisonConfig) => runComparison(comparisonConfig, {
|
|
27
|
+
storageDir: storageContext.storageDir,
|
|
28
|
+
}),
|
|
29
|
+
}, options.signal);
|
|
30
|
+
}
|
|
31
|
+
/** Crawls selected routes and atomically merges them into a stored baseline. */
|
|
32
|
+
export async function updateSnapshotRoutesFromConfig(config, baselineSnapshotId, options = {}) {
|
|
33
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
34
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
35
|
+
return updateSnapshotRoutes(config, baselineSnapshotId, snapshotRepository, (snapshotConfig, signal) => createSnapshot(snapshotConfig, snapshotRepository, signal), options.signal);
|
|
13
36
|
}
|
|
14
37
|
/**
|
|
15
38
|
* Starts a snapshot job and returns the job status.
|
|
@@ -28,16 +51,17 @@ export async function createSnapshotFromConfig(config) {
|
|
|
28
51
|
* Orchestrates calls to Snapshot Manager, Rules Engine Parser (if needed),
|
|
29
52
|
* DOM Processor, and Diff Engine.
|
|
30
53
|
*/
|
|
31
|
-
export async function runComparison(config) {
|
|
32
|
-
const
|
|
54
|
+
export async function runComparison(config, options = {}) {
|
|
55
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
56
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
33
57
|
const rulesEngine = await RulesEngine.create(config.ruleset);
|
|
34
|
-
const comparisonRepository = await ComparisonRepository.
|
|
58
|
+
const comparisonRepository = await ComparisonRepository.createWithStorageContext(config.comparisonName, {
|
|
35
59
|
beforeSnapshotId: config.beforeSnapshotId,
|
|
36
60
|
afterSnapshotId: config.afterSnapshotId,
|
|
37
61
|
rulesUsedIdentifier: typeof config.ruleset === "string"
|
|
38
62
|
? config.ruleset
|
|
39
63
|
: config.ruleset?.name,
|
|
40
|
-
});
|
|
64
|
+
}, storageContext);
|
|
41
65
|
const diff = await compareSnapshots(config, snapshotRepository, comparisonRepository, rulesEngine);
|
|
42
66
|
// Convert SnapshotDiff to ComparisonSummary
|
|
43
67
|
return {
|
|
@@ -58,12 +82,49 @@ export async function runComparison(config) {
|
|
|
58
82
|
resultsPath: diff.resultsPath,
|
|
59
83
|
};
|
|
60
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Parses and validates a rules.breakcheck directory into the intermediate
|
|
87
|
+
* JSON document used by the rules engine.
|
|
88
|
+
*/
|
|
89
|
+
export async function compileRulesDsl(rulesDirectory) {
|
|
90
|
+
const ruleset = await processRulesDsl(rulesDirectory);
|
|
91
|
+
await RulesEngine.create(ruleset);
|
|
92
|
+
return {
|
|
93
|
+
rules: ruleset.rules,
|
|
94
|
+
regions: ruleset.regions ?? [],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
61
97
|
/**
|
|
62
98
|
* Lists all available snapshots with their details
|
|
63
99
|
*/
|
|
64
|
-
export async function listSnapshots() {
|
|
65
|
-
const
|
|
100
|
+
export async function listSnapshots(options = {}) {
|
|
101
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
102
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
66
103
|
return snapshotRepository.listSnapshots();
|
|
67
104
|
}
|
|
68
|
-
|
|
105
|
+
/** Deletes one named snapshot. */
|
|
106
|
+
export async function deleteSnapshot(name, options = {}) {
|
|
107
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
108
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
109
|
+
return snapshotRepository.deleteSnapshot(name);
|
|
110
|
+
}
|
|
111
|
+
/** Deletes all snapshots and returns the names that were removed. */
|
|
112
|
+
export async function deleteAllSnapshots(options = {}) {
|
|
113
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
114
|
+
const snapshotRepository = SnapshotRepository.createWithStorageContext(storageContext);
|
|
115
|
+
return snapshotRepository.deleteAllSnapshots();
|
|
116
|
+
}
|
|
117
|
+
/** Deletes one named comparison. */
|
|
118
|
+
export async function deleteComparison(name, options = {}) {
|
|
119
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
120
|
+
const comparisonRepository = ComparisonRepository.openWithStorageContext(storageContext);
|
|
121
|
+
return comparisonRepository.deleteComparison(name);
|
|
122
|
+
}
|
|
123
|
+
/** Deletes all comparisons and returns the names that were removed. */
|
|
124
|
+
export async function deleteAllComparisons(options = {}) {
|
|
125
|
+
const storageContext = await resolveStorageContext(options.storageDir);
|
|
126
|
+
const comparisonRepository = ComparisonRepository.openWithStorageContext(storageContext);
|
|
127
|
+
return comparisonRepository.deleteAllComparisons();
|
|
128
|
+
}
|
|
129
|
+
export { logger, };
|
|
69
130
|
//# sourceMappingURL=index.js.map
|
package/dist/api/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAa1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAsB,EACtB,OAAO,GAAqB,EAAE;IAE9B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AACpE,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAuB,EACvB,OAAO,GAAqB,EAAE;IAE9B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,oBAAoB,CACzB,MAAM,EACN;QACE,kBAAkB;QAClB,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,CACzC,cAAc,CAAC,cAAc,EAAE,kBAAkB,EAAE,MAAM,CAAC;QAC5D,aAAa,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAClC,aAAa,CAAC,gBAAgB,EAAE;YAC9B,UAAU,EAAE,cAAc,CAAC,UAAU;SACtC,CAAC;KACL,EACD,OAAO,CAAC,MAAM,CACf,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,MAAsB,EACtB,kBAA0B,EAC1B,OAAO,GAAqB,EAAE;IAE9B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,oBAAoB,CACzB,MAAM,EACN,kBAAkB,EAClB,kBAAkB,EAClB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,CACzB,cAAc,CAAC,cAAc,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAC5D,OAAO,CAAC,MAAM,CACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,0BAA0B;AAC1B,2BAA2B;AAC3B,2CAA2C;AAE3C;;GAEG;AACH,8BAA8B;AAC9B,kBAAkB;AAClB,2CAA2C;AAE3C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAwB,EACxB,OAAO,GAAmB,EAAE;IAE5B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,MAAM,oBAAoB,GACxB,MAAM,oBAAoB,CAAC,wBAAwB,CACjD,MAAM,CAAC,cAAc,EACrB;QACE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,mBAAmB,EACjB,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAChC,CAAC,CAAC,MAAM,CAAC,OAAO;YAChB,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI;KAC3B,EACD,cAAc,CACf,CAAC;IAEJ,MAAM,IAAI,GAAG,MAAM,gBAAgB,CACjC,MAAM,EACN,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,CACZ,CAAC;IAEF,4CAA4C;IAC5C,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,cAAc;QACnC,MAAM,EAAE,WAAW;QACnB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;QAC/C,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,uBAAuB,EAAE,EAAE;QAC3B,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,cAAsB;IAEtB,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,cAAc,CAAC,CAAC;IACtD,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAO,GAAmB,EAAE;IAC9D,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,kBAAkB,CAAC,aAAa,EAAE,CAAC;AAC5C,CAAC;AAED,kCAAkC;AAClC,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,OAAO,GAAmB,EAAE;IAE5B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,kBAAkB,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAO,GAAmB,EAAE;IAE5B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,kBAAkB,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;AACjD,CAAC;AAED,oCAAoC;AACpC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,OAAO,GAAmB,EAAE;IAE5B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,oBAAoB,GACxB,oBAAoB,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,oBAAoB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAO,GAAmB,EAAE;IAE5B,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,oBAAoB,GACxB,oBAAoB,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;IAC9D,OAAO,oBAAoB,CAAC,oBAAoB,EAAE,CAAC;AACrD,CAAC;AAED,OAAO,EACL,MAAM,GAQP,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ComparisonConfig, ComparisonSummary, SiteCheckConfig, SiteCheckResult, SnapshotConfig, SnapshotResult } from "../../types/api.js";
|
|
2
|
+
import type { SnapshotRepository } from "../snapshot/classes/SnapshotRepository.js";
|
|
3
|
+
export interface SiteCheckOperations {
|
|
4
|
+
snapshotRepository: SnapshotRepository;
|
|
5
|
+
createSnapshot: (config: SnapshotConfig, signal?: AbortSignal) => Promise<SnapshotResult>;
|
|
6
|
+
runComparison: (config: ComparisonConfig) => Promise<ComparisonSummary>;
|
|
7
|
+
}
|
|
8
|
+
/** Runs an exact-route regression check using the supplied core operations. */
|
|
9
|
+
export declare function runSiteCheck(config: SiteCheckConfig, operations: SiteCheckOperations, signal?: AbortSignal): Promise<SiteCheckResult>;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { resolveUrlPaths } from "../crawler/url-paths.js";
|
|
2
|
+
import { validateSnapshotRoutes } from "../snapshot/route-coverage.js";
|
|
3
|
+
/** Runs an exact-route regression check using the supplied core operations. */
|
|
4
|
+
export async function runSiteCheck(config, operations, signal) {
|
|
5
|
+
signal?.throwIfAborted();
|
|
6
|
+
if (config.name === config.baselineSnapshotId) {
|
|
7
|
+
throw new Error("The check snapshot name must differ from the baseline snapshot ID.");
|
|
8
|
+
}
|
|
9
|
+
if ((config.crawlSettings.includePatterns?.length ?? 0) > 0 ||
|
|
10
|
+
(config.crawlSettings.excludePatterns?.length ?? 0) > 0) {
|
|
11
|
+
throw new Error("Exact-route checks cannot use crawl includePatterns or excludePatterns.");
|
|
12
|
+
}
|
|
13
|
+
const manifest = resolveUrlPaths(config.baseUrl, config.routes);
|
|
14
|
+
if (manifest.issues.length > 0) {
|
|
15
|
+
throw new Error(manifest.issues.map((issue) => issue.message).join("; "));
|
|
16
|
+
}
|
|
17
|
+
await operations.snapshotRepository.loadSnapshot(config.baselineSnapshotId);
|
|
18
|
+
signal?.throwIfAborted();
|
|
19
|
+
const snapshotResult = await operations.createSnapshot({
|
|
20
|
+
baseUrl: config.baseUrl,
|
|
21
|
+
name: config.name,
|
|
22
|
+
urlPaths: manifest.paths,
|
|
23
|
+
crawlSettings: {
|
|
24
|
+
...config.crawlSettings,
|
|
25
|
+
baseUrl: config.baseUrl,
|
|
26
|
+
includePatterns: [],
|
|
27
|
+
excludePatterns: [],
|
|
28
|
+
},
|
|
29
|
+
}, signal);
|
|
30
|
+
if (snapshotResult.status === "failed") {
|
|
31
|
+
return {
|
|
32
|
+
status: "failed",
|
|
33
|
+
baseUrl: config.baseUrl,
|
|
34
|
+
baselineSnapshotId: config.baselineSnapshotId,
|
|
35
|
+
snapshotId: snapshotResult.snapshotId,
|
|
36
|
+
routes: manifest.paths,
|
|
37
|
+
crawlErrors: snapshotResult.errors.map((error) => ({
|
|
38
|
+
url: config.baseUrl,
|
|
39
|
+
message: error.message,
|
|
40
|
+
...(error.statusCode === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: { statusCode: error.statusCode }),
|
|
43
|
+
})),
|
|
44
|
+
errors: [snapshotResult.message],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
signal?.throwIfAborted();
|
|
48
|
+
const afterSnapshot = await operations.snapshotRepository.loadSnapshot(snapshotResult.snapshotId);
|
|
49
|
+
const failures = snapshotResult.errors.map((error) => `${error.url}: ${error.message}`);
|
|
50
|
+
failures.push(...(await validateSnapshotRoutes(afterSnapshot, manifest.paths)));
|
|
51
|
+
signal?.throwIfAborted();
|
|
52
|
+
if (failures.length > 0) {
|
|
53
|
+
return {
|
|
54
|
+
status: "failed",
|
|
55
|
+
baseUrl: config.baseUrl,
|
|
56
|
+
baselineSnapshotId: config.baselineSnapshotId,
|
|
57
|
+
snapshotId: snapshotResult.snapshotId,
|
|
58
|
+
routes: manifest.paths,
|
|
59
|
+
crawlErrors: snapshotResult.errors,
|
|
60
|
+
errors: failures,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
let comparison;
|
|
64
|
+
try {
|
|
65
|
+
comparison = await operations.runComparison({
|
|
66
|
+
beforeSnapshotId: config.baselineSnapshotId,
|
|
67
|
+
afterSnapshotId: snapshotResult.snapshotId,
|
|
68
|
+
comparisonName: config.name,
|
|
69
|
+
ruleset: config.ruleset,
|
|
70
|
+
urls: manifest.paths,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return {
|
|
75
|
+
status: "failed",
|
|
76
|
+
baseUrl: config.baseUrl,
|
|
77
|
+
baselineSnapshotId: config.baselineSnapshotId,
|
|
78
|
+
snapshotId: snapshotResult.snapshotId,
|
|
79
|
+
routes: manifest.paths,
|
|
80
|
+
crawlErrors: [],
|
|
81
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (signal?.aborted)
|
|
85
|
+
signal.throwIfAborted();
|
|
86
|
+
if (comparison.pagesWithErrors > 0) {
|
|
87
|
+
return {
|
|
88
|
+
status: "failed",
|
|
89
|
+
baseUrl: config.baseUrl,
|
|
90
|
+
baselineSnapshotId: config.baselineSnapshotId,
|
|
91
|
+
snapshotId: snapshotResult.snapshotId,
|
|
92
|
+
routes: manifest.paths,
|
|
93
|
+
crawlErrors: [],
|
|
94
|
+
errors: [
|
|
95
|
+
`Comparison could not process ${comparison.pagesWithErrors} page(s).`,
|
|
96
|
+
],
|
|
97
|
+
comparison,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const status = comparison.pagesWithDifferences > 0 ||
|
|
101
|
+
comparison.newUrls.length > 0 ||
|
|
102
|
+
comparison.removedUrls.length > 0
|
|
103
|
+
? "differences"
|
|
104
|
+
: "passed";
|
|
105
|
+
return {
|
|
106
|
+
status,
|
|
107
|
+
baseUrl: config.baseUrl,
|
|
108
|
+
baselineSnapshotId: config.baselineSnapshotId,
|
|
109
|
+
snapshotId: snapshotResult.snapshotId,
|
|
110
|
+
routes: manifest.paths,
|
|
111
|
+
crawlErrors: [],
|
|
112
|
+
errors: [],
|
|
113
|
+
comparison,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/check/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAqBvE,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAuB,EACvB,UAA+B,EAC/B,MAAoB;IAEpB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QACvD,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,EACvD,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5E,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,cAAc,GAAG,MAAM,UAAU,CAAC,cAAc,CACpD;QACE,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,QAAQ,CAAC,KAAK;QACxB,aAAa,EAAE;YACb,GAAG,MAAM,CAAC,aAAa;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,eAAe,EAAE,EAAE;YACnB,eAAe,EAAE,EAAE;SACpB;KACF,EACD,MAAM,CACP,CAAC;IAEF,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAc,EAAE,CAAC,CAAC;gBAC7D,GAAG,EAAE,MAAM,CAAC,OAAO;gBACnB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS;oBAChC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;aACtC,CAAC,CAAC;YACH,MAAM,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC;SACjC,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,kBAAkB,CAAC,YAAY,CACpE,cAAc,CAAC,UAAU,CAC1B,CAAC;IACF,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CACxC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,OAAO,EAAE,CAC5C,CAAC;IACF,QAAQ,CAAC,IAAI,CACX,GAAG,CAAC,MAAM,sBAAsB,CAAC,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CACjE,CAAC;IAEF,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,WAAW,EAAE,cAAc,CAAC,MAAM;YAClC,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,UAA6B,CAAC;IAClC,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC;YAC1C,gBAAgB,EAAE,MAAM,CAAC,kBAAkB;YAC3C,eAAe,EAAE,cAAc,CAAC,UAAU;YAC1C,cAAc,EAAE,MAAM,CAAC,IAAI;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE,QAAQ,CAAC,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,WAAW,EAAE,EAAE;YACf,MAAM,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SACjE,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,EAAE,OAAO;QAAE,MAAM,CAAC,cAAc,EAAE,CAAC;IAC7C,IAAI,UAAU,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,WAAW,EAAE,EAAE;YACf,MAAM,EAAE;gBACN,gCAAgC,UAAU,CAAC,eAAe,WAAW;aACtE;YACD,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GACV,UAAU,CAAC,oBAAoB,GAAG,CAAC;QACnC,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAC7B,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,QAAQ,CAAC;IACf,OAAO;QACL,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,UAAU,EAAE,cAAc,CAAC,UAAU;QACrC,MAAM,EAAE,QAAQ,CAAC,KAAK;QACtB,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,EAAE;QACV,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type StorageContext } from "../../../lib/storage.js";
|
|
1
2
|
import { ComparisonIndex, ComparisonMetadata, PageDiff } from "../../../types/compare.js";
|
|
2
3
|
export declare class ComparisonRepository {
|
|
3
4
|
private readonly comparisonsDir;
|
|
@@ -9,6 +10,12 @@ export declare class ComparisonRepository {
|
|
|
9
10
|
* Creates a new comparison repository instance and initializes it with the given name and metadata.
|
|
10
11
|
*/
|
|
11
12
|
static create(name: string, metadata: ComparisonMetadata, comparisonsDir?: string): Promise<ComparisonRepository>;
|
|
13
|
+
/** Creates and initializes a comparison in a shared artifact context. */
|
|
14
|
+
static createWithStorageContext(name: string, metadata: ComparisonMetadata, storageContext: StorageContext): Promise<ComparisonRepository>;
|
|
15
|
+
/** Opens the comparison store without initializing a named comparison. */
|
|
16
|
+
static open(comparisonsDir?: string): Promise<ComparisonRepository>;
|
|
17
|
+
/** Opens a comparison store in a shared artifact context. */
|
|
18
|
+
static openWithStorageContext(storageContext: StorageContext): ComparisonRepository;
|
|
12
19
|
/**
|
|
13
20
|
* Initializes a new comparison, creating directories and saving initial metadata.
|
|
14
21
|
*/
|
|
@@ -22,4 +29,8 @@ export declare class ComparisonRepository {
|
|
|
22
29
|
*/
|
|
23
30
|
finalizeComparison(): Promise<string>;
|
|
24
31
|
getIndex(): ComparisonIndex;
|
|
32
|
+
/** Deletes one named comparison without removing the storage root. */
|
|
33
|
+
deleteComparison(name: string): Promise<boolean>;
|
|
34
|
+
/** Deletes all direct child comparison directories and returns their names. */
|
|
35
|
+
deleteAllComparisons(): Promise<string[]>;
|
|
25
36
|
}
|
|
@@ -3,6 +3,7 @@ import * as path from "path";
|
|
|
3
3
|
import { promisify } from "util";
|
|
4
4
|
import * as zlib from "zlib";
|
|
5
5
|
import { findRootDir } from "../../../lib/root.js";
|
|
6
|
+
import { deleteAllStorageEntries, deleteStorageEntry, resolveStorageEntry, } from "../../../lib/storage.js";
|
|
6
7
|
const gzip = promisify(zlib.gzip);
|
|
7
8
|
export class ComparisonRepository {
|
|
8
9
|
comparisonsDir;
|
|
@@ -16,18 +17,31 @@ export class ComparisonRepository {
|
|
|
16
17
|
* Creates a new comparison repository instance and initializes it with the given name and metadata.
|
|
17
18
|
*/
|
|
18
19
|
static async create(name, metadata, comparisonsDir) {
|
|
19
|
-
const
|
|
20
|
-
const defaultComparisonsDir = path.join(rootDir, "comparisons");
|
|
21
|
-
const instance = new ComparisonRepository(comparisonsDir || defaultComparisonsDir);
|
|
20
|
+
const instance = await ComparisonRepository.open(comparisonsDir);
|
|
22
21
|
await instance.initialize(name, metadata);
|
|
23
22
|
return instance;
|
|
24
23
|
}
|
|
24
|
+
/** Creates and initializes a comparison in a shared artifact context. */
|
|
25
|
+
static async createWithStorageContext(name, metadata, storageContext) {
|
|
26
|
+
const instance = ComparisonRepository.openWithStorageContext(storageContext);
|
|
27
|
+
await instance.initialize(name, metadata);
|
|
28
|
+
return instance;
|
|
29
|
+
}
|
|
30
|
+
/** Opens the comparison store without initializing a named comparison. */
|
|
31
|
+
static async open(comparisonsDir) {
|
|
32
|
+
const resolvedComparisonsDir = comparisonsDir ?? path.join(await findRootDir(), "comparisons");
|
|
33
|
+
return new ComparisonRepository(resolvedComparisonsDir);
|
|
34
|
+
}
|
|
35
|
+
/** Opens a comparison store in a shared artifact context. */
|
|
36
|
+
static openWithStorageContext(storageContext) {
|
|
37
|
+
return new ComparisonRepository(storageContext.comparisonsDir);
|
|
38
|
+
}
|
|
25
39
|
/**
|
|
26
40
|
* Initializes a new comparison, creating directories and saving initial metadata.
|
|
27
41
|
*/
|
|
28
42
|
async initialize(name, metadata) {
|
|
43
|
+
this.comparisonDir = resolveStorageEntry(this.comparisonsDir, name, "comparison");
|
|
29
44
|
await fs.mkdir(this.comparisonsDir, { recursive: true });
|
|
30
|
-
this.comparisonDir = path.join(this.comparisonsDir, name);
|
|
31
45
|
this.diffsDir = path.join(this.comparisonDir, "diffs");
|
|
32
46
|
// Clean up previous results
|
|
33
47
|
await fs.rm(this.comparisonDir, { recursive: true, force: true });
|
|
@@ -73,5 +87,13 @@ export class ComparisonRepository {
|
|
|
73
87
|
getIndex() {
|
|
74
88
|
return this.index;
|
|
75
89
|
}
|
|
90
|
+
/** Deletes one named comparison without removing the storage root. */
|
|
91
|
+
async deleteComparison(name) {
|
|
92
|
+
return deleteStorageEntry(this.comparisonsDir, name, "comparison");
|
|
93
|
+
}
|
|
94
|
+
/** Deletes all direct child comparison directories and returns their names. */
|
|
95
|
+
async deleteAllComparisons() {
|
|
96
|
+
return deleteAllStorageEntries(this.comparisonsDir, "comparison");
|
|
97
|
+
}
|
|
76
98
|
}
|
|
77
99
|
//# sourceMappingURL=ComparisonRepository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComparisonRepository.js","sourceRoot":"","sources":["../../../../src/core/compare/classes/ComparisonRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ComparisonRepository.js","sourceRoot":"","sources":["../../../../src/core/compare/classes/ComparisonRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,14 @@ export async function comparePage(before, after) {
|
|
|
15
15
|
const beforeContent = beautify(before.content, beautifyOptions);
|
|
16
16
|
const afterContent = beautify(after.content, beautifyOptions);
|
|
17
17
|
const patch = createPatch(url, beforeContent, afterContent);
|
|
18
|
-
const differences = diffLines(beforeContent, afterContent)
|
|
18
|
+
const differences = diffLines(beforeContent, afterContent).map((change) => {
|
|
19
|
+
const { added, removed, ...unchangedFields } = change;
|
|
20
|
+
return {
|
|
21
|
+
...unchangedFields,
|
|
22
|
+
...(added ? { added } : {}),
|
|
23
|
+
...(removed ? { removed } : {}),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
19
26
|
const hasDifferences = differences.some((diff) => diff.added || diff.removed);
|
|
20
27
|
return { url, differences, hasDifferences, patch };
|
|
21
28
|
}
|
|
@@ -31,15 +38,20 @@ export async function compareSnapshots(config, snapshotRepository, comparisonRep
|
|
|
31
38
|
const beforeUrls = Object.keys(beforeSnapshot.index.urls);
|
|
32
39
|
const afterUrls = new Set(Object.keys(afterSnapshot.index.urls));
|
|
33
40
|
const urlsToCompare = config.urls || beforeUrls;
|
|
41
|
+
const requestedUrls = config.urls === undefined ? undefined : new Set(config.urls);
|
|
34
42
|
const rulesUsedIdentifier = typeof config.ruleset === "string" ? config.ruleset : config.ruleset?.name;
|
|
35
43
|
// Find new and removed URLs
|
|
36
|
-
const newUrls = [...afterUrls].filter((url) => !beforeUrls.includes(url)
|
|
37
|
-
|
|
44
|
+
const newUrls = [...afterUrls].filter((url) => !beforeUrls.includes(url) &&
|
|
45
|
+
(requestedUrls === undefined || requestedUrls.has(url)));
|
|
46
|
+
const removedUrls = beforeUrls.filter((url) => !afterUrls.has(url) &&
|
|
47
|
+
(requestedUrls === undefined || requestedUrls.has(url)));
|
|
38
48
|
let pagesWithErrors = 0;
|
|
39
49
|
// Compare pages one by one
|
|
40
50
|
for (const url of urlsToCompare) {
|
|
41
51
|
if (!afterUrls.has(url))
|
|
42
52
|
continue; // Skip URLs not in the "after" snapshot
|
|
53
|
+
if (!beforeSnapshot.index.urls[url])
|
|
54
|
+
continue; // New URLs are reported above
|
|
43
55
|
const beforePage = await beforeSnapshot.getPage(url);
|
|
44
56
|
const afterPage = await afterSnapshot.getPage(url);
|
|
45
57
|
if (!beforePage || !afterPage) {
|
|
@@ -61,7 +73,11 @@ export async function compareSnapshots(config, snapshotRepository, comparisonRep
|
|
|
61
73
|
// Return the summary data
|
|
62
74
|
return {
|
|
63
75
|
status: "completed",
|
|
64
|
-
overallResult: finalIndex.metadata.pagesWithDifferences > 0
|
|
76
|
+
overallResult: finalIndex.metadata.pagesWithDifferences > 0 ||
|
|
77
|
+
newUrls.length > 0 ||
|
|
78
|
+
removedUrls.length > 0
|
|
79
|
+
? "fail"
|
|
80
|
+
: "pass",
|
|
65
81
|
beforeSnapshotId: config.beforeSnapshotId,
|
|
66
82
|
afterSnapshotId: config.afterSnapshotId,
|
|
67
83
|
rulesUsedIdentifier,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compare/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,IAAI,MAAM,MAAM,CAAC;AAQxB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAoB,EACpB,KAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAEvB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;IAEjC,MAAM,eAAe,GAAG;QACtB,WAAW,EAAE,CAAC;QACd,iBAAiB,EAAE,KAAK;QACxB,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC;KAChD,CAAC;IACF,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAE9D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAe,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compare/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { CrawlerConfig } from "../../types/api.js";
|
|
2
2
|
import type { CrawlResult } from "../../types/crawler.js";
|
|
3
|
+
interface CrawlerRuntime {
|
|
4
|
+
run(startUrls: string[]): Promise<unknown>;
|
|
5
|
+
teardown(): Promise<void>;
|
|
6
|
+
}
|
|
3
7
|
export declare class BreakcheckCrawler {
|
|
4
8
|
private config;
|
|
5
9
|
private crawler;
|
|
@@ -9,7 +13,9 @@ export declare class BreakcheckCrawler {
|
|
|
9
13
|
constructor(config: CrawlerConfig, options?: {
|
|
10
14
|
startUrls?: string[];
|
|
11
15
|
followLinks?: boolean;
|
|
16
|
+
crawler?: CrawlerRuntime;
|
|
12
17
|
});
|
|
13
18
|
private createCrawler;
|
|
14
|
-
crawl(): Promise<CrawlResult>;
|
|
19
|
+
crawl(signal?: AbortSignal): Promise<CrawlResult>;
|
|
15
20
|
}
|
|
21
|
+
export {};
|