@imwz/wp-pattern-sentinel 1.1.4 → 1.1.5
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 +4 -0
- package/package.json +1 -1
- package/src/main.js +8 -2
- package/src/validation.js +47 -18
package/README.md
CHANGED
|
@@ -212,6 +212,10 @@ node -e "
|
|
|
212
212
|
|
|
213
213
|
`block_validation` errors also surface Gutenberg's human-readable issue messages (e.g. `"Expected attribute 'class' of value '…' but got '…'"`), so you no longer need to open the browser console to identify what failed.
|
|
214
214
|
|
|
215
|
+
A block can also pass validation only because one of its block type's deprecations accepted the markup and migrated it. The editor reports such a block as valid, but it saves different markup, and it shows as broken the next time the page is opened. Sentinel re-validates every parsed block against its original markup and reports these as `block_validation` errors reading "Block was migrated by a deprecation and will save different markup". A common cause is an attribute the block does not support, such as `aria-hidden` on `core/paragraph`.
|
|
216
|
+
|
|
217
|
+
`--cache` entries record the Sentinel version that passed them, so upgrading Sentinel re-validates every pattern once.
|
|
218
|
+
|
|
215
219
|
## npm publish
|
|
216
220
|
|
|
217
221
|
When ready to publish:
|
package/package.json
CHANGED
package/src/main.js
CHANGED
|
@@ -17,6 +17,12 @@ import { log, formatResult, printSummary } from './format.js';
|
|
|
17
17
|
|
|
18
18
|
const CACHE_FILE = '.sentinel-cache.json';
|
|
19
19
|
|
|
20
|
+
// Cache entries record the Sentinel version that passed them, so a release
|
|
21
|
+
// that adds or tightens a check re-validates patterns that passed before it.
|
|
22
|
+
const SENTINEL_VERSION = JSON.parse(
|
|
23
|
+
fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')
|
|
24
|
+
).version;
|
|
25
|
+
|
|
20
26
|
function loadCache() {
|
|
21
27
|
try {
|
|
22
28
|
return JSON.parse(fs.readFileSync(path.join(process.cwd(), CACHE_FILE), 'utf8'));
|
|
@@ -67,7 +73,7 @@ export async function main() {
|
|
|
67
73
|
try {
|
|
68
74
|
const content = fs.readFileSync(file, 'utf8');
|
|
69
75
|
const key = path.relative(process.cwd(), file);
|
|
70
|
-
if (cache[key]?.passed && cache[key]?.hash === hashContent(content)) {
|
|
76
|
+
if (cache[key]?.passed && cache[key]?.hash === hashContent(content) && cache[key]?.version === SENTINEL_VERSION) {
|
|
71
77
|
skipped.push(file);
|
|
72
78
|
} else {
|
|
73
79
|
pending.push(file);
|
|
@@ -153,7 +159,7 @@ export async function main() {
|
|
|
153
159
|
for (const result of results) {
|
|
154
160
|
const key = path.relative(process.cwd(), result.patternPath);
|
|
155
161
|
if (result.passed) {
|
|
156
|
-
cache[key] = { hash: result.hash, passed: true, checkedAt: new Date().toISOString() };
|
|
162
|
+
cache[key] = { hash: result.hash, passed: true, version: SENTINEL_VERSION, checkedAt: new Date().toISOString() };
|
|
157
163
|
} else {
|
|
158
164
|
delete cache[key];
|
|
159
165
|
}
|
package/src/validation.js
CHANGED
|
@@ -1,30 +1,59 @@
|
|
|
1
1
|
import { log } from './format.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Walk the block tree and collect any blocks where isValid === false
|
|
4
|
+
* Walk the block tree and collect any blocks where isValid === false, plus any
|
|
5
|
+
* block a deprecation silently migrated.
|
|
6
|
+
*
|
|
7
|
+
* When a block fails validation, the parser tries the block type's
|
|
8
|
+
* deprecations; if one accepts the markup, the block is migrated and reported
|
|
9
|
+
* as isValid: true with no issues, yet its attributes have changed and it will
|
|
10
|
+
* save different markup. The editor then shows the block as broken on the next
|
|
11
|
+
* load. Example: core/paragraph with aria-hidden="true" is taken by an old
|
|
12
|
+
* paragraph deprecation that drops fontFamily and keeps the whole <p> as the
|
|
13
|
+
* block's text, so the first save writes a <p> nested inside another <p>.
|
|
14
|
+
* Re-running validateBlock() on the parsed block compares what it will save
|
|
15
|
+
* against the original markup, which catches this.
|
|
5
16
|
*/
|
|
6
17
|
export async function checkBlockValidation(page, verbose = false) {
|
|
7
18
|
const start = Date.now();
|
|
8
19
|
if (verbose) log(' → Checking block validation...', 'gray');
|
|
9
20
|
try {
|
|
10
21
|
const errors = await page.evaluate(() => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const formatIssues = issues => (issues ?? []).map(issue => {
|
|
23
|
+
try {
|
|
24
|
+
return (issue.args ?? [])
|
|
25
|
+
.map(a => (typeof a === 'string' ? a : JSON.stringify(a)))
|
|
26
|
+
.join(' ');
|
|
27
|
+
} catch { return 'unknown issue'; }
|
|
28
|
+
});
|
|
29
|
+
const validateBlock = window.wp.blocks.validateBlock;
|
|
30
|
+
const migratedIssues = block => {
|
|
31
|
+
if (!validateBlock || block.isValid !== true || block.name === 'core/missing') return null;
|
|
32
|
+
const [isValid, issues] = validateBlock(block);
|
|
33
|
+
return isValid ? null : issues;
|
|
34
|
+
};
|
|
35
|
+
const walk = blocks => blocks.flatMap(block => {
|
|
36
|
+
const migrated = migratedIssues(block);
|
|
37
|
+
return [
|
|
38
|
+
...(block.isValid === false
|
|
39
|
+
? [{
|
|
40
|
+
blockId: block.clientId,
|
|
41
|
+
blockName: block.name,
|
|
42
|
+
error: 'Block validation failed',
|
|
43
|
+
validationIssues: formatIssues(block.validationIssues),
|
|
44
|
+
}]
|
|
45
|
+
: []),
|
|
46
|
+
...(migrated
|
|
47
|
+
? [{
|
|
48
|
+
blockId: block.clientId,
|
|
49
|
+
blockName: block.name,
|
|
50
|
+
error: 'Block was migrated by a deprecation and will save different markup',
|
|
51
|
+
validationIssues: formatIssues(migrated),
|
|
52
|
+
}]
|
|
53
|
+
: []),
|
|
54
|
+
...walk(block.innerBlocks ?? []),
|
|
55
|
+
];
|
|
56
|
+
});
|
|
28
57
|
return walk(window.wp.data.select('core/block-editor').getBlocks());
|
|
29
58
|
});
|
|
30
59
|
if (verbose) log(` → Block validation complete (${Date.now() - start}ms)`, 'gray');
|