@d-zero/archaeologist 2.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/analyze-child-process.d.ts +4 -1
- package/dist/analyze-child-process.js +65 -36
- package/dist/analyze-main-process.d.ts +2 -1
- package/dist/analyze-main-process.js +19 -6
- package/dist/cli.js +34 -14
- package/dist/modules/diff-text.d.ts +21 -0
- package/dist/modules/diff-text.js +45 -0
- package/dist/modules/get-data.d.ts +3 -0
- package/dist/modules/get-data.js +10 -9
- package/dist/modules/normalize-text-document.d.ts +5 -0
- package/dist/modules/normalize-text-document.js +15 -0
- package/dist/parse-types.d.ts +5 -0
- package/dist/parse-types.js +8 -0
- package/dist/read-config.js +2 -8
- package/dist/types.d.ts +11 -2
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -12,16 +12,22 @@
|
|
|
12
12
|
## CLI
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
npx @d-zero/archaeologist -f <
|
|
15
|
+
npx @d-zero/archaeologist -f <listfile> [options]
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
URLリストを持つファイルを指定して実行します。
|
|
19
19
|
|
|
20
20
|
### オプション
|
|
21
21
|
|
|
22
|
-
- `-f, --
|
|
22
|
+
- `-f, --listfile <filepath>`: URLリストを持つファイルのパス(必須)
|
|
23
|
+
- `-t, --type <types>`: 比較タイプの指定(`image,dom,text`、カンマ区切り)
|
|
24
|
+
- `-s, --selector <selector>`: 比較対象を限定するCSSセレクター
|
|
25
|
+
- `-i, --ignore <selector>`: 無視するCSSセレクター
|
|
26
|
+
- `--devices <devices>`: デバイス指定(`desktop,mobile,tablet`、カンマ区切り)
|
|
27
|
+
- `--freeze <filepath>`: フリーズモード用ファイルパス
|
|
23
28
|
- `--limit <number>`: 並列実行数の上限(デフォルト: 10)
|
|
24
29
|
- `--debug`: デバッグモード(デフォルト: false)
|
|
30
|
+
- `--verbose`: 詳細ログモード(デフォルト: false)
|
|
25
31
|
|
|
26
32
|
### ファイルフォーマット
|
|
27
33
|
|
|
@@ -53,7 +59,7 @@ https://example.com/xyz/001
|
|
|
53
59
|
|
|
54
60
|
## ページフック
|
|
55
61
|
|
|
56
|
-
[Frontmatter](https://jekyllrb.com/docs/front-matter/)の`hooks`に配列としてスクリプトファイルのパスを渡すと、ページを開いた後(厳密には
|
|
62
|
+
[Frontmatter](https://jekyllrb.com/docs/front-matter/)の`hooks`に配列としてスクリプトファイルのパスを渡すと、ページを開いた後(厳密にはPuppeteerの`waitUntil: 'networkidle0'`のタイミング直後)にそれらのスクリプトを実行します。スクリプトは配列の順番通りに逐次実行されます。
|
|
57
63
|
|
|
58
64
|
```txt
|
|
59
65
|
---
|
|
@@ -4,6 +4,9 @@ export type ChildProcessParams = {
|
|
|
4
4
|
list: readonly URLPair[];
|
|
5
5
|
dir: string;
|
|
6
6
|
useOldMode: boolean;
|
|
7
|
-
|
|
7
|
+
types?: readonly string[];
|
|
8
|
+
selector?: string;
|
|
9
|
+
ignore?: string;
|
|
10
|
+
devices?: readonly string[];
|
|
8
11
|
hooks?: readonly PageHook[];
|
|
9
12
|
};
|
|
@@ -4,11 +4,13 @@ import { createChildProcess } from '@d-zero/puppeteer-dealer';
|
|
|
4
4
|
import { delay } from '@d-zero/shared/delay';
|
|
5
5
|
import c from 'ansi-colors';
|
|
6
6
|
import { diffImages } from './modules/diff-images.js';
|
|
7
|
+
import { diffText } from './modules/diff-text.js';
|
|
7
8
|
import { diffTree } from './modules/diff-tree.js';
|
|
8
9
|
import { getData } from './modules/get-data.js';
|
|
10
|
+
import { normalizeTextDocument } from './modules/normalize-text-document.js';
|
|
9
11
|
import { score } from './utils.js';
|
|
10
12
|
createChildProcess((param) => {
|
|
11
|
-
const { list, dir,
|
|
13
|
+
const { list, dir, types = ['image', 'dom', 'text'], selector, ignore, devices, } = param;
|
|
12
14
|
return {
|
|
13
15
|
async eachPage({ page, url: urlA, index }, logger) {
|
|
14
16
|
const urlPair = list.find(([url]) => url === urlA);
|
|
@@ -18,7 +20,10 @@ createChildProcess((param) => {
|
|
|
18
20
|
const dataPair = [];
|
|
19
21
|
for (const url of urlPair) {
|
|
20
22
|
const data = await getData(page, url, {
|
|
21
|
-
htmlDiffOnly,
|
|
23
|
+
htmlDiffOnly: !types.includes('image'),
|
|
24
|
+
selector,
|
|
25
|
+
ignore,
|
|
26
|
+
devices,
|
|
22
27
|
}, logger);
|
|
23
28
|
dataPair.push(data);
|
|
24
29
|
await delay(600);
|
|
@@ -36,47 +41,71 @@ createChildProcess((param) => {
|
|
|
36
41
|
if (!screenshotB) {
|
|
37
42
|
throw new Error(`Failed to get screenshotB: ${id}`);
|
|
38
43
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
let image = null;
|
|
45
|
+
if (types.includes('image')) {
|
|
46
|
+
const imageDiff = await diffImages(screenshotA, screenshotB, (phase, data) => {
|
|
47
|
+
switch (phase) {
|
|
48
|
+
case 'create': {
|
|
49
|
+
logger(`${sizeName} ${outputUrl} 🖼️ Create images`);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'resize': {
|
|
53
|
+
const { width, height } = data;
|
|
54
|
+
logger(`${sizeName} ${outputUrl} ↔️ Resize images to ${width}x${height}`);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'diff': {
|
|
58
|
+
logger(`${sizeName} ${outputUrl} 📊 Compare images`);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
53
61
|
}
|
|
62
|
+
});
|
|
63
|
+
if (imageDiff) {
|
|
64
|
+
logger(`${sizeName} ${outputUrl} 🧩 Matches ${score(imageDiff.matches, 0.9)}`);
|
|
65
|
+
await delay(1500);
|
|
66
|
+
await writeFile(path.resolve(dir, `${id}_a.png`), imageDiff.images.a);
|
|
67
|
+
await writeFile(path.resolve(dir, `${id}_b.png`), imageDiff.images.b);
|
|
68
|
+
const outFilePath = path.resolve(dir, `${id}_diff.png`);
|
|
69
|
+
logger(`${sizeName} ${outputUrl} 📊 Save diff image to ${path.relative(dir, outFilePath)}`);
|
|
70
|
+
await writeFile(outFilePath, imageDiff.images.diff);
|
|
71
|
+
image = {
|
|
72
|
+
matches: imageDiff.matches,
|
|
73
|
+
file: outFilePath,
|
|
74
|
+
};
|
|
54
75
|
}
|
|
55
|
-
}
|
|
56
|
-
let
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await writeFile(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
}
|
|
77
|
+
let dom = null;
|
|
78
|
+
if (types.includes('dom')) {
|
|
79
|
+
const htmlDiff = diffTree(a.url, b.url, screenshotA.domTree, screenshotB.domTree);
|
|
80
|
+
const outFilePath = path.resolve(dir, `${id}_html.diff`);
|
|
81
|
+
await writeFile(outFilePath, htmlDiff.result, { encoding: 'utf8' });
|
|
82
|
+
dom = {
|
|
83
|
+
matches: htmlDiff.matches,
|
|
84
|
+
diff: htmlDiff.changed ? htmlDiff.result : null,
|
|
85
|
+
file: outFilePath,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
let text = null;
|
|
89
|
+
if (types.includes('text')) {
|
|
90
|
+
const contentA = normalizeTextDocument(screenshotA.text.textContent);
|
|
91
|
+
const contentB = normalizeTextDocument(screenshotB.text.textContent);
|
|
92
|
+
const altTextListA = screenshotA.text.altTextList.join('\n');
|
|
93
|
+
const altTextListB = screenshotB.text.altTextList.join('\n');
|
|
94
|
+
const textA = `${contentA}\n\n${altTextListA}`;
|
|
95
|
+
const textB = `${contentB}\n\n${altTextListB}`;
|
|
96
|
+
const textDiff = diffText(a.url, b.url, textA, textB);
|
|
97
|
+
const outFilePath = path.resolve(dir, `${id}_text.diff`);
|
|
98
|
+
await writeFile(outFilePath, `${textDiff.phrases.result}\n\n${textDiff.tokens.result}`, { encoding: 'utf8' });
|
|
99
|
+
text = {
|
|
100
|
+
matches: textDiff.tokens.matches,
|
|
101
|
+
diff: textDiff.tokens.changed ? textDiff.tokens.result : null,
|
|
67
102
|
file: outFilePath,
|
|
68
103
|
};
|
|
69
104
|
}
|
|
70
|
-
const htmlDiff = diffTree(a.url, b.url, screenshotA.domTree, screenshotB.domTree);
|
|
71
|
-
const outFilePath = path.resolve(dir, `${id}_html.diff`);
|
|
72
|
-
await writeFile(outFilePath, htmlDiff.result, { encoding: 'utf8' });
|
|
73
105
|
screenshotResult[name] = {
|
|
74
106
|
image,
|
|
75
|
-
dom
|
|
76
|
-
|
|
77
|
-
diff: htmlDiff.changed ? htmlDiff.result : null,
|
|
78
|
-
file: outFilePath,
|
|
79
|
-
},
|
|
107
|
+
dom,
|
|
108
|
+
text,
|
|
80
109
|
};
|
|
81
110
|
}
|
|
82
111
|
const result = {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { AnalyzeOptions, URLPair } from './types.js';
|
|
2
|
+
import type { DealOptions } from '@d-zero/dealer';
|
|
2
3
|
/**
|
|
3
4
|
*
|
|
4
5
|
* @param list
|
|
5
6
|
* @param options
|
|
6
7
|
*/
|
|
7
|
-
export declare function analyze(list: readonly URLPair[], options?: AnalyzeOptions): Promise<void>;
|
|
8
|
+
export declare function analyze(list: readonly URLPair[], options?: AnalyzeOptions & DealOptions): Promise<void>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { mkdir } from 'node:fs/promises';
|
|
1
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { createProcess, deal } from '@d-zero/puppeteer-dealer';
|
|
4
4
|
import c from 'ansi-colors';
|
|
5
|
+
import stripAnsi from 'strip-ansi';
|
|
5
6
|
import { analyzeUrlList } from './modules/analize-url.js';
|
|
6
7
|
import { score } from './utils.js';
|
|
7
8
|
/**
|
|
@@ -22,25 +23,37 @@ export async function analyze(list, options) {
|
|
|
22
23
|
list,
|
|
23
24
|
dir,
|
|
24
25
|
useOldMode,
|
|
25
|
-
|
|
26
|
+
types: options?.types,
|
|
27
|
+
selector: options?.selector,
|
|
28
|
+
ignore: options?.ignore,
|
|
29
|
+
devices: options?.devices,
|
|
26
30
|
hooks: options?.hooks ?? [],
|
|
27
31
|
}, {
|
|
28
32
|
...options,
|
|
29
33
|
headless: useOldMode ? 'shell' : true,
|
|
30
34
|
});
|
|
31
|
-
},
|
|
32
|
-
|
|
35
|
+
}, {
|
|
36
|
+
...options,
|
|
37
|
+
each(result) {
|
|
38
|
+
results.push(result);
|
|
39
|
+
},
|
|
33
40
|
});
|
|
34
41
|
const output = [];
|
|
35
42
|
for (const result of results) {
|
|
36
43
|
output.push(c.gray(`${result.target.join(' vs ')}`));
|
|
37
|
-
for (const [sizeName, { image, dom }] of Object.entries(result.screenshots)) {
|
|
44
|
+
for (const [sizeName, { image, dom, text }] of Object.entries(result.screenshots)) {
|
|
38
45
|
if (image) {
|
|
39
46
|
const { matches, file } = image;
|
|
40
47
|
output.push(` ${c.bgMagenta(` ${sizeName} `)} ${score(matches, 0.9)} ${file}`);
|
|
41
48
|
}
|
|
42
|
-
|
|
49
|
+
if (dom) {
|
|
50
|
+
output.push(` ${c.bgBlueBright(' HTML ')}: ${score(dom.matches, 0.995)} ${dom.file}`);
|
|
51
|
+
}
|
|
52
|
+
if (text) {
|
|
53
|
+
output.push(` ${c.bgGreenBright(' TEXT ')}: ${score(text.matches, 0.995)} ${text.file}`);
|
|
54
|
+
}
|
|
43
55
|
}
|
|
44
56
|
}
|
|
57
|
+
await writeFile(path.resolve(dir, 'RESULT.txt'), stripAnsi(output.join('\n').replaceAll(dir, '.')), 'utf8');
|
|
45
58
|
process.stdout.write(output.join('\n') + '\n');
|
|
46
59
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,32 +1,52 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import { createCLI, parseCommonOptions, parseList } from '@d-zero/cli-core';
|
|
3
3
|
import { analyze } from './analyze-main-process.js';
|
|
4
4
|
import { freeze } from './freeze-main-process.js';
|
|
5
5
|
import { readConfig } from './read-config.js';
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const { options, hasConfigFile } = createCLI({
|
|
7
|
+
aliases: {
|
|
8
8
|
f: 'listfile',
|
|
9
|
+
t: 'type',
|
|
10
|
+
s: 'selector',
|
|
11
|
+
i: 'ignore',
|
|
12
|
+
},
|
|
13
|
+
usage: ['Usage: archaeologist -f <listfile> [--limit <number>]'],
|
|
14
|
+
parseArgs: (cli) => ({
|
|
15
|
+
...parseCommonOptions(cli),
|
|
16
|
+
listfile: cli.listfile,
|
|
17
|
+
type: cli.type,
|
|
18
|
+
freeze: cli.freeze,
|
|
19
|
+
selector: cli.selector,
|
|
20
|
+
ignore: cli.ignore,
|
|
21
|
+
devices: cli.devices ??
|
|
22
|
+
// Alias for devices
|
|
23
|
+
cli.device,
|
|
24
|
+
}),
|
|
25
|
+
validateArgs: (options) => {
|
|
26
|
+
return !!(options.listfile?.length || options.freeze?.length);
|
|
9
27
|
},
|
|
10
28
|
});
|
|
11
|
-
if (
|
|
12
|
-
const { pairList, hooks } = await readConfig(
|
|
29
|
+
if (hasConfigFile) {
|
|
30
|
+
const { pairList, hooks } = await readConfig(options.listfile);
|
|
13
31
|
await analyze(pairList, {
|
|
14
32
|
hooks,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
33
|
+
types: options.type ? parseList(options.type) : undefined,
|
|
34
|
+
selector: options.selector,
|
|
35
|
+
ignore: options.ignore,
|
|
36
|
+
devices: options.devices ? parseList(options.devices) : undefined,
|
|
37
|
+
limit: options.limit,
|
|
38
|
+
debug: options.debug,
|
|
39
|
+
verbose: options.verbose,
|
|
18
40
|
});
|
|
19
41
|
process.exit(0);
|
|
20
42
|
}
|
|
21
|
-
if (
|
|
22
|
-
const { pairList, hooks } = await readConfig(
|
|
43
|
+
if (options.freeze) {
|
|
44
|
+
const { pairList, hooks } = await readConfig(options.freeze);
|
|
23
45
|
const list = pairList.map(([urlA]) => urlA);
|
|
24
46
|
await freeze(list, {
|
|
25
47
|
hooks,
|
|
26
|
-
limit:
|
|
27
|
-
debug:
|
|
48
|
+
limit: options.limit,
|
|
49
|
+
debug: options.debug,
|
|
28
50
|
});
|
|
29
51
|
process.exit(0);
|
|
30
52
|
}
|
|
31
|
-
process.stderr.write('Usage: archaeologist -f <listfile> [--limit <number>]\n');
|
|
32
|
-
process.exit(1);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param urlA
|
|
4
|
+
* @param urlB
|
|
5
|
+
* @param phraseA
|
|
6
|
+
* @param phraseB
|
|
7
|
+
*/
|
|
8
|
+
export declare function diffText(urlA: string, urlB: string, phraseA: string, phraseB: string): {
|
|
9
|
+
phrases: {
|
|
10
|
+
changed: boolean;
|
|
11
|
+
maxLine: number;
|
|
12
|
+
matches: number;
|
|
13
|
+
result: string;
|
|
14
|
+
};
|
|
15
|
+
tokens: {
|
|
16
|
+
changed: boolean;
|
|
17
|
+
maxLine: number;
|
|
18
|
+
matches: number;
|
|
19
|
+
result: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getTokenizer } from 'kuromojin';
|
|
2
|
+
import { diffTree } from './diff-tree.js';
|
|
3
|
+
const tokenizer = await getTokenizer();
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param text
|
|
7
|
+
*/
|
|
8
|
+
function tokenList(text) {
|
|
9
|
+
return tokenizer
|
|
10
|
+
.tokenize(text)
|
|
11
|
+
.filter((token) => token.surface_form.trim() !== '')
|
|
12
|
+
.map((token) => `${token.surface_form}:${token.pos}:${token.pos_detail_1}`);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param tokens
|
|
17
|
+
*/
|
|
18
|
+
function frequencyMap(tokens) {
|
|
19
|
+
const map = new Map();
|
|
20
|
+
for (const token of tokens) {
|
|
21
|
+
map.set(token, (map.get(token) ?? 0) + 1);
|
|
22
|
+
}
|
|
23
|
+
return map
|
|
24
|
+
.entries()
|
|
25
|
+
.map(([token, frequency]) => `${token} x${frequency}`)
|
|
26
|
+
.toArray()
|
|
27
|
+
.toSorted((a, b) => a.localeCompare(b));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param urlA
|
|
32
|
+
* @param urlB
|
|
33
|
+
* @param phraseA
|
|
34
|
+
* @param phraseB
|
|
35
|
+
*/
|
|
36
|
+
export function diffText(urlA, urlB, phraseA, phraseB) {
|
|
37
|
+
const tokensA = tokenList(phraseA);
|
|
38
|
+
const tokensB = tokenList(phraseB);
|
|
39
|
+
const frequencyMapA = frequencyMap(tokensA).join('\n');
|
|
40
|
+
const frequencyMapB = frequencyMap(tokensB).join('\n');
|
|
41
|
+
return {
|
|
42
|
+
phrases: diffTree(urlA, urlB, phraseA, phraseB),
|
|
43
|
+
tokens: diffTree(urlA, urlB, frequencyMapA, frequencyMapB),
|
|
44
|
+
};
|
|
45
|
+
}
|
package/dist/modules/get-data.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { distill } from '@d-zero/html-distiller';
|
|
2
|
+
import { defaultSizes } from '@d-zero/puppeteer-page-scan';
|
|
2
3
|
import { screenshotListener, screenshot } from '@d-zero/puppeteer-screenshot';
|
|
3
4
|
/**
|
|
4
5
|
*
|
|
@@ -9,19 +10,19 @@ import { screenshotListener, screenshot } from '@d-zero/puppeteer-screenshot';
|
|
|
9
10
|
*/
|
|
10
11
|
export async function getData(page, url, options, update) {
|
|
11
12
|
const htmlDiffOnly = options.htmlDiffOnly ?? false;
|
|
13
|
+
const devices = options.devices ?? ['desktop', 'mobile'];
|
|
14
|
+
const sizes = {};
|
|
15
|
+
for (const device of devices) {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
sizes[device] = defaultSizes[device];
|
|
18
|
+
}
|
|
12
19
|
const screenshots = await screenshot(page, url, {
|
|
13
|
-
sizes
|
|
14
|
-
desktop: {
|
|
15
|
-
width: 1280,
|
|
16
|
-
},
|
|
17
|
-
mobile: {
|
|
18
|
-
width: 375,
|
|
19
|
-
resolution: 2,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
20
|
+
sizes,
|
|
22
21
|
hooks: options?.hooks ?? [],
|
|
23
22
|
listener: screenshotListener(update),
|
|
24
23
|
domOnly: htmlDiffOnly,
|
|
24
|
+
selector: options.selector,
|
|
25
|
+
ignore: options.ignore,
|
|
25
26
|
});
|
|
26
27
|
const data = { url, screenshots: {} };
|
|
27
28
|
for (const [sizeName, screenshot] of Object.entries(screenshots)) {
|
package/dist/read-config.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
1
|
import { readPageHooks } from '@d-zero/puppeteer-page-scan';
|
|
4
2
|
import { toList } from '@d-zero/readtext/list';
|
|
5
|
-
import
|
|
3
|
+
import { readConfigFile } from '@d-zero/shared/config-reader';
|
|
6
4
|
/**
|
|
7
5
|
*
|
|
8
6
|
* @param filePath
|
|
9
7
|
*/
|
|
10
8
|
export async function readConfig(filePath) {
|
|
11
|
-
const
|
|
12
|
-
const content =
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
fm(fileContent);
|
|
9
|
+
const { content, baseDir } = await readConfigFile(filePath);
|
|
15
10
|
const urlList = toList(content.body);
|
|
16
11
|
const pairList = urlList.map((urlStr) => {
|
|
17
12
|
const url = new URL(urlStr);
|
|
@@ -20,7 +15,6 @@ export async function readConfig(filePath) {
|
|
|
20
15
|
`${content.attributes.comparisonHost}${url.pathname}${url.search}`,
|
|
21
16
|
];
|
|
22
17
|
});
|
|
23
|
-
const baseDir = path.dirname(filePath);
|
|
24
18
|
const hooks = await readPageHooks(content.attributes?.hooks ?? [], baseDir);
|
|
25
19
|
return {
|
|
26
20
|
pairList,
|
package/dist/types.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ export type Result = {
|
|
|
13
13
|
};
|
|
14
14
|
export type MediaResult = {
|
|
15
15
|
image: ImageResult | null;
|
|
16
|
-
dom: DOMResult;
|
|
16
|
+
dom: DOMResult | null;
|
|
17
|
+
text: TextResult | null;
|
|
17
18
|
};
|
|
18
19
|
export type ImageResult = {
|
|
19
20
|
matches: number;
|
|
@@ -24,10 +25,18 @@ export type DOMResult = {
|
|
|
24
25
|
diff: string | null;
|
|
25
26
|
file: string;
|
|
26
27
|
};
|
|
28
|
+
export type TextResult = {
|
|
29
|
+
matches: number;
|
|
30
|
+
diff: string | null;
|
|
31
|
+
file: string;
|
|
32
|
+
};
|
|
27
33
|
export interface ArchaeologistOptions extends AnalyzeOptions {
|
|
28
34
|
}
|
|
29
35
|
export interface AnalyzeOptions extends GeneralOptions {
|
|
30
|
-
readonly
|
|
36
|
+
readonly types?: readonly string[];
|
|
37
|
+
readonly selector?: string;
|
|
38
|
+
readonly ignore?: string;
|
|
39
|
+
readonly devices?: readonly string[];
|
|
31
40
|
}
|
|
32
41
|
export interface FreezeOptions extends GeneralOptions {
|
|
33
42
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d-zero/archaeologist",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Uncover visual and HTML differences in web pages with precision",
|
|
5
5
|
"author": "D-ZERO",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"private": false,
|
|
8
7
|
"publishConfig": {
|
|
9
8
|
"access": "public"
|
|
10
9
|
},
|
|
@@ -15,9 +14,7 @@
|
|
|
15
14
|
"types": "./dist/index.d.ts"
|
|
16
15
|
}
|
|
17
16
|
},
|
|
18
|
-
"bin":
|
|
19
|
-
"archaeologist": "./dist/cli.js"
|
|
20
|
-
},
|
|
17
|
+
"bin": "./dist/cli.js",
|
|
21
18
|
"files": [
|
|
22
19
|
"dist"
|
|
23
20
|
],
|
|
@@ -27,27 +24,30 @@
|
|
|
27
24
|
"clean": "tsc --build --clean"
|
|
28
25
|
},
|
|
29
26
|
"dependencies": {
|
|
30
|
-
"@d-zero/
|
|
31
|
-
"@d-zero/
|
|
32
|
-
"@d-zero/
|
|
33
|
-
"@d-zero/puppeteer-
|
|
34
|
-
"@d-zero/puppeteer-
|
|
35
|
-
"@d-zero/
|
|
36
|
-
"@d-zero/
|
|
27
|
+
"@d-zero/cli-core": "1.1.0",
|
|
28
|
+
"@d-zero/fs": "0.2.1",
|
|
29
|
+
"@d-zero/html-distiller": "1.0.4",
|
|
30
|
+
"@d-zero/puppeteer-dealer": "0.5.1",
|
|
31
|
+
"@d-zero/puppeteer-page-scan": "4.0.2",
|
|
32
|
+
"@d-zero/puppeteer-screenshot": "3.1.1",
|
|
33
|
+
"@d-zero/readtext": "1.1.5",
|
|
34
|
+
"@d-zero/shared": "0.9.1",
|
|
37
35
|
"ansi-colors": "4.1.3",
|
|
38
|
-
"diff": "8.0.
|
|
36
|
+
"diff": "8.0.2",
|
|
39
37
|
"front-matter": "4.0.2",
|
|
40
38
|
"jimp": "1.6.0",
|
|
39
|
+
"kuromojin": "3.0.1",
|
|
41
40
|
"minimist": "1.2.8",
|
|
42
41
|
"parse-diff": "0.11.1",
|
|
43
42
|
"pixelmatch": "7.1.0",
|
|
44
43
|
"pngjs": "7.0.0",
|
|
45
|
-
"puppeteer": "24.
|
|
44
|
+
"puppeteer": "24.10.2",
|
|
45
|
+
"strip-ansi": "7.1.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/diff": "8.0.0",
|
|
49
49
|
"@types/pixelmatch": "5.2.6",
|
|
50
50
|
"@types/pngjs": "6.0.5"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "1218a023e62c79efeece6350d561f2e1906be7ea"
|
|
53
53
|
}
|