Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 'use strict' /** * Resolve the master-CSV header row into known field indices. * * Matching is deterministic: each field maps to a normalized substring of the * header text. This tolerates minor header wording/casing differences without * ever guessing semantics. If a required column is missing the caller throws, * surfacing the headers it actually found. */ const FIELD_PATTERNS = { name: [/proposed icon/, /icon name/], designStatus: [/design status/], iconType: [/icon type/], color: [/icon colou?r/, /^colou?r$/], synonyms: [/synonym/], assetSubmitted: [/asset submitted/, /^asset/], targetBuild: [/target build/, /^build$/] } const REQUIRED_FIELDS = ['name', 'designStatus', 'iconType', 'assetSubmitted', 'targetBuild'] function normalize(header) { return String(header || '') .toLowerCase() .replace(/\s+/g, ' ') .trim() } function resolveColumns(headerRow) { const normalized = headerRow.map(normalize) const map = {} for (const [field, patterns] of Object.entries(FIELD_PATTERNS)) { const index = normalized.findIndex(h => patterns.some(p => p.test(h))) if (index !== -1) { map[field] = index } } const missing = REQUIRED_FIELDS.filter(field => map[field] === undefined) if (missing.length > 0) { const err = new Error( `Required CSV column(s) not found: ${missing.join(', ')}. ` + `Headers seen: [${headerRow.map(h => `"${h}"`).join(', ')}]` ) err.code = 'MISSING_COLUMNS' throw err } return map } module.exports = { resolveColumns, REQUIRED_FIELDS } |