#!/usr/bin/env node /** * check-preview-flag-dev-only.mjs — the "preview unreleased content" flag never reaches a built bundle. * * globalThis.DXM_PREVIEW_UNRELEASED = true makes a page show what is withheld from the public (the whole-India * country poster). It is set only under the Vite dev server (library/elements/defineMapElement.js, behind * import.meta.env.DEV, a compile-time false in every build). The built tree (public/dx-maps) goes to the research * 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. */ 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 TEXT = /\.(m?js|html|json|css|txt)$/ function* walk(dir) { let names = [] try { names = readdirSync(dir) } catch (_) { return } for (const n of names) { if (n === 'node_modules' || n.startsWith('.')) continue const p = join(dir, n) let st; try { st = statSync(p) } catch (_) { continue } if (st.isDirectory()) yield* walk(p) else yield p } } 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)`) } return fails } 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`) }) } return fails } const built = () => [...walk(join(ROOT, 'public'))].filter((p) => TEXT.test(p)).map((p) => [relative(ROOT, p), readFileSync(p, 'utf8')]) const source = () => [...walk(join(ROOT, 'library')), ...walk(join(ROOT, 'plugin-designs'))] .filter((p) => /\.(m?js|vue)$/.test(p) && !/\/(scripts|tests?|__tests__)\//.test(p)) .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') 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') }