Merge origin/development into studio/poster-registry
This commit is contained in:
commit
c7b77b0a12
2 changed files with 20 additions and 17 deletions
|
|
@ -8,18 +8,19 @@
|
|||
* landing and to DX Life's /dx-maps, so one assignment there would print India publicly.
|
||||
*
|
||||
* ASSERTS:
|
||||
* A. no file under public/ ASSIGNS the flag (any spelling a minifier writes: = true, =!0, =1, …); reading it
|
||||
* (=== true) is fine;
|
||||
* B. every SOURCE line that assigns it (library/, plugin-designs/, outside scripts/ and tests) is behind
|
||||
* import.meta.env.DEV on the same line.
|
||||
* `--self-test` plants each defect in memory and exits 0 only if both are caught.
|
||||
* A. NO file under public/ MENTIONS the flag at all. An assignment there would turn the preview on, and a READ
|
||||
* there means the withheld path itself shipped, behind a global any embedding page or console can set (that
|
||||
* IS shipping it). Every read is compiled away by its DEV guard, so the built tree never names the flag;
|
||||
* B. every SOURCE line that mentions it, read OR write (library/, plugin-designs/, outside scripts/ and tests;
|
||||
* comments aside), carries import.meta.env.DEV on the same line.
|
||||
* `--self-test` plants each defect in memory and exits 0 only if all are caught.
|
||||
*/
|
||||
import { readFileSync, readdirSync, statSync } from 'node:fs'
|
||||
import { join, dirname, relative } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const ASSIGN = /DXM_PREVIEW_UNRELEASED\s*=(?!=)/
|
||||
const MENTION = /DXM_PREVIEW_UNRELEASED/
|
||||
const TEXT = /\.(m?js|html|json|css|txt)$/
|
||||
|
||||
function* walk(dir) {
|
||||
|
|
@ -37,9 +38,9 @@ function* walk(dir) {
|
|||
function auditBuilt(files) {
|
||||
const fails = []
|
||||
for (const [rel, text] of files) {
|
||||
if (!ASSIGN.test(text)) continue
|
||||
const line = text.split('\n').findIndex((l) => ASSIGN.test(l)) + 1
|
||||
fails.push(`A ${rel}:${line} ASSIGNS DXM_PREVIEW_UNRELEASED in the built tree (it would show withheld content publicly)`)
|
||||
if (!MENTION.test(text)) continue
|
||||
const line = text.split('\n').findIndex((l) => MENTION.test(l)) + 1
|
||||
fails.push(`A ${rel}:${line} names DXM_PREVIEW_UNRELEASED in the built tree (a setter would show withheld content; a read means the withheld path shipped)`)
|
||||
}
|
||||
return fails
|
||||
}
|
||||
|
|
@ -47,7 +48,7 @@ function auditSource(files) {
|
|||
const fails = []
|
||||
for (const [rel, text] of files) {
|
||||
text.split('\n').forEach((l, i) => {
|
||||
if (ASSIGN.test(l) && !/import\.meta\.env\.DEV/.test(l) && !/^\s*(\/\/|\*)/.test(l)) fails.push(`B ${rel}:${i + 1} assigns DXM_PREVIEW_UNRELEASED outside an import.meta.env.DEV guard`)
|
||||
if (MENTION.test(l) && !/import\.meta\.env\.DEV/.test(l) && !/^\s*(\/\/|\*|\/\*)/.test(l)) fails.push(`B ${rel}:${i + 1} reads or writes DXM_PREVIEW_UNRELEASED outside an import.meta.env.DEV guard`)
|
||||
})
|
||||
}
|
||||
return fails
|
||||
|
|
@ -59,14 +60,16 @@ const source = () => [...walk(join(ROOT, 'library')), ...walk(join(ROOT, 'plugin
|
|||
.map((p) => [relative(ROOT, p), readFileSync(p, 'utf8')])
|
||||
|
||||
if (process.argv.includes('--self-test')) {
|
||||
const a = auditBuilt([['public/dx-maps/x/x.js', 'var a=1;globalThis.DXM_PREVIEW_UNRELEASED=!0;'], ['public/dx-maps/x/ok.js', 'if(globalThis.DXM_PREVIEW_UNRELEASED===true)f()']])
|
||||
const b = auditSource([['library/x.js', 'globalThis.DXM_PREVIEW_UNRELEASED = true'], ['library/ok.js', 'if (import.meta.env.DEV) globalThis.DXM_PREVIEW_UNRELEASED = true']])
|
||||
const okA = a.length === 1 && /x\/x\.js/.test(a[0]), okB = b.length === 1 && /library\/x\.js/.test(b[0])
|
||||
console.log(okA ? '✓ caught: a built bundle that assigns the flag (minified =!0); a read (===) is not flagged' : '✗ MISSED: the built-tree assignment')
|
||||
console.log(okB ? '✓ caught: a source assignment outside import.meta.env.DEV; the guarded one passes' : '✗ MISSED: the unguarded source assignment')
|
||||
const a = auditBuilt([['public/dx-maps/x/set.js', 'var a=1;globalThis.DXM_PREVIEW_UNRELEASED=!0;'], ['public/dx-maps/x/read.js', 'if(globalThis.DXM_PREVIEW_UNRELEASED===!0)showIndia()'], ['public/dx-maps/x/ok.js', 'showOthers()']])
|
||||
const b = auditSource([['library/set.js', 'globalThis.DXM_PREVIEW_UNRELEASED = true'], ['library/read.js', "export const previewUnreleased = () => typeof globalThis !== 'undefined' && globalThis.DXM_PREVIEW_UNRELEASED === true"],
|
||||
['library/ok.js', 'if (import.meta.env.DEV) globalThis.DXM_PREVIEW_UNRELEASED = true'], ['library/okread.js', 'export const p = () => import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true'], ['library/c.js', '// DXM_PREVIEW_UNRELEASED is named in a comment']])
|
||||
const okA = a.length === 2 && a.some((x) => /set\.js/.test(x)) && a.some((x) => /read\.js/.test(x))
|
||||
const okB = b.length === 2 && b.some((x) => /library\/set\.js/.test(x)) && b.some((x) => /library\/read\.js/.test(x))
|
||||
console.log(okA ? '✓ caught: a built bundle that SETS the flag (=!0) and one that READS it (the withheld path shipped); a clean one passes' : '✗ MISSED: a built-tree setter or reader')
|
||||
console.log(okB ? '✓ caught: an unguarded source SETTER and an unguarded source READ (the plain previewUnreleased()); the DEV-guarded ones and comments pass' : '✗ MISSED: an unguarded source setter or read')
|
||||
process.exitCode = okA && okB ? 0 : 1
|
||||
} else {
|
||||
const fails = [...auditBuilt(built()), ...auditSource(source())]
|
||||
if (fails.length) { for (const f of fails) console.log('✗ ' + f); console.log(`FAIL check:preview-flag-dev-only (${fails.length})`); process.exitCode = 1 }
|
||||
else console.log('PASS check:preview-flag-dev-only — no built file assigns DXM_PREVIEW_UNRELEASED; every source assignment is behind import.meta.env.DEV')
|
||||
else console.log('PASS check:preview-flag-dev-only — no built file names DXM_PREVIEW_UNRELEASED; every source read and write is behind import.meta.env.DEV')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@
|
|||
"check:coverage-consistent": "the gospel-resources surfaces must agree: no resource on an ISO RESERVED code (und/mul/mis/zxx), every resourced code NAMED, table reach recounted off the pins, no invented URL, tiers reconcile. Static, sub-second. Self-test: `bun run check:coverage-consistent:poison`, all 12 clauses (A-L) must fail. Clause L is the one that is not about consistency: it fails when the link-verification record goes stale, because 'link checked' is a claim about the present tense. Written after the same drift defect was found by hand three times.",
|
||||
"check:csv-shape": "the export must OPEN as a table: header on line 0, every row matching. Run the `check:csv-shape:self-test` script for the NEGATIVE test (forces the provenance comment back to line 0 IN MEMORY and requires this gate to REJECT it) — the header used to claim 'NEGATIVE-TESTED' with no way to re-run it.",
|
||||
"check:poster-sizes": "the shared poster-size ladder (library/constants/posterSizes.js) is right: picker order = ladder, dot-free keys, portrait only, the sheets glue up to the finished size, photo slots on exactly 66x66 + 60x96, paper prints and the rest go to a print-shop PDF, every alias resolves, paperFor() picks Letter or A4 by region. Run the `check:poster-sizes:self-test` script for the NEGATIVE test",
|
||||
"check:preview-flag-dev-only": "the flag that previews withheld content (globalThis.DXM_PREVIEW_UNRELEASED, e.g. the whole-India poster) never reaches a built bundle: no file under public/ assigns it in any spelling a minifier writes, and every source assignment is behind import.meta.env.DEV (set only by the Vite dev server, the pilot's hot-reload preview). The built tree goes to the research landing and DX Life's /dx-maps, where the flag would show India publicly. Run the `check:preview-flag-dev-only:self-test` script for the NEGATIVE test (2 planted defects).",
|
||||
"check:preview-flag-dev-only": "the flag that previews withheld content (globalThis.DXM_PREVIEW_UNRELEASED, e.g. the whole-India poster) never reaches a built bundle: NO file under public/ names it at all (a setter would turn the preview on; a read would mean the withheld path itself shipped), and every source line that reads OR writes it carries import.meta.env.DEV (set only by the Vite dev server, the pilot's hot-reload preview). The built tree goes to the research landing and DX Life's /dx-maps, where the flag would show India publicly. Run the `check:preview-flag-dev-only:self-test` script for the NEGATIVE test (a built setter, a built read, an unguarded source setter and an unguarded source read).",
|
||||
"check:pin-hint-floor": "the pin-hint pill sits at the map's bottom on a page that scrolls (the fold is not an obstacle there) and is still lifted above the fold on a full-screen page; the legend sheet and the licence credit still lift it; PinHint.vue takes its floor from pinHintFloor.js. Run the `check:pin-hint-floor:self-test` script for the NEGATIVE test",
|
||||
"check:no-fleet-names": "tracked source (not data/, public/ or the translation catalogues) names no build-team member, attributes no request to a user and carries no dated QA-round tag; an allowance is a named LINE, never a whole file. Run the `check:no-fleet-names:self-test` script for the NEGATIVE test",
|
||||
"check:dashboard-filter-a11y": "the dashboard's cross-filter is operable and audible: every filter chip is a <button type=\"button\"> with an aria-label naming the ACTION (a filter that can be set by keyboard must be clearable by keyboard), the shell carries exactly ONE always-rendered polite role=\"status\" region so a brush that changes a number far from the control is announced once rather than six times or not at all, and no resize handle's accessible name is a raw English literal. AST over the parsed templates plus the built bundle — no browser.",
|
||||
|
|
|
|||
Loading…
Reference in a new issue