Skip to content

Commit

Permalink
Use vitest, add noUncheckedIndexedAccess, update lint (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin authored Nov 10, 2024
1 parent f8bf7bb commit 19dc43f
Show file tree
Hide file tree
Showing 9 changed files with 1,310 additions and 688 deletions.
55 changes: 18 additions & 37 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,50 +1,31 @@
import typescriptEslint from '@typescript-eslint/eslint-plugin'
import prettier from 'eslint-plugin-prettier'
import tsParser from '@typescript-eslint/parser'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import js from '@eslint/js'
import { FlatCompat } from '@eslint/eslintrc'
import eslint from '@eslint/js'
import tseslint from 'typescript-eslint'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
})

export default [
...compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
'prettier',
),
export default tseslint.config(
{
ignores: ['esm/**/*', 'dist/**/*', '*.js', '*.mjs', 'example/*'],
},
{
plugins: {
'@typescript-eslint': typescriptEslint,
prettier,
},

languageOptions: {
parser: tsParser,
ecmaVersion: 5,
sourceType: 'script',

parserOptions: {
project: './tsconfig.lint.json',
project: ['./tsconfig.lint.json'],
tsconfigRootDir: import.meta.dirname,
},
},

},
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylisticTypeChecked,
...tseslint.configs.strictTypeChecked,
{
rules: {
curly: 'error',

'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
caughtErrors: 'none',
ignoreRestSiblings: true,
},
],
Expand All @@ -57,8 +38,8 @@ export default [
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'prettier/prettier': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
},
},
]

)
19 changes: 12 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@
"node": ">=6"
},
"scripts": {
"test": "jest",
"coverage": "npm test -- --coverage",
"lint": "eslint --report-unused-disable-directives --max-warnings 0 src test",
"test": "vitest",
"lint": "eslint --report-unused-disable-directives --max-warnings 0",
"docs": "documentation readme src/parse.ts --section=API --shallow",
"postdocs": "prettier --write README.md",
"clean": "rimraf dist esm",
"build:esm": "tsc --target es2018 --outDir esm",
"build:es5": "tsc --target es2015 --module commonjs --outDir dist",
"build": "npm run build:esm && npm run build:es5",
"prebuild": "npm run clean && npm run lint",
"preversion": "npm run lint && npm test && npm run build",
"preversion": "npm run lint && npm test --run && npm run build",
"version": "standard-changelog && git add CHANGELOG.md",
"postversion": "git push --follow-tags"
},
Expand All @@ -43,18 +42,21 @@
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.7.0",
"@types/jest": "^29.2.4",
"@typescript-eslint/eslint-plugin": "^7.17.0",
"@typescript-eslint/parser": "^7.17.0",
"@typescript-eslint/eslint-plugin": "^8.8.1",
"@typescript-eslint/parser": "^8.8.1",
"@vitest/coverage-v8": "^2.1.3",
"documentation": "^14.0.1",
"eslint": "^9.7.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^56.0.0",
"jest": "^29.3.1",
"prettier": "^3.2.4",
"rimraf": "^6.0.1",
"standard-changelog": "^6.0.0",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"typescript-eslint": "^8.8.1"
},
"keywords": [
"vcf",
Expand All @@ -64,5 +66,8 @@
],
"publishConfig": {
"access": "public"
},
"dependencies": {
"vitest": "^2.1.3"
}
}
12 changes: 6 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,31 @@ export function parseBreakend(breakendString: string): Breakend | undefined {
Replacement: breakendString.slice(0, breakendString.length - 1),
}
} else if (breakendString.startsWith('<')) {
const res = breakendString.match('<(.*)>(.*)')
const res = /<(.*)>(.*)/.exec(breakendString)
if (!res) {
throw new Error(`failed to parse ${breakendString}`)
}
const Replacement = res?.[2]
const Replacement = res[2]
return Replacement
? {
Join: 'left',
Replacement,
MateDirection: 'right',
MatePosition: `<${res?.[1]}>:1`,
MatePosition: `<${res[1]!}>:1`,
}
: undefined
} else if (breakendString.includes('<')) {
const res = breakendString.match('(.*)<(.*)>')
const res = /(.*)<(.*)>/.exec(breakendString)
if (!res) {
throw new Error(`failed to parse ${breakendString}`)
}
const Replacement = res?.[1]
const Replacement = res[1]
return Replacement
? {
Join: 'right',
Replacement,
MateDirection: 'right',
MatePosition: `<${res?.[2]}>:1`,
MatePosition: `<${res[2]!}>:1`,
}
: undefined
}
Expand Down
42 changes: 21 additions & 21 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function Variant(stuff: any) {
function decodeURIComponentNoThrow(uri: string) {
try {
return decodeURIComponent(uri)
} catch (e) {
} catch (_e) {
// avoid throwing exception on a failure to decode URI component
return uri
}
Expand All @@ -33,7 +33,7 @@ export default class VCF {
header: string
strict?: boolean
}) {
if (!header?.length) {
if (!header.length) {
throw new Error('empty header received')
}
const headerLines = header.split(/[\r\n]+/).filter(line => line)
Expand Down Expand Up @@ -98,12 +98,11 @@ export default class VCF {
formatKeys.forEach(key => {
genotypes[sample][key] = null
})
rest[index]
.split(':')
rest[index]!.split(':')
.filter(f => f)
.forEach((val, index) => {
let thisValue: unknown
if (val === '' || val === '.' || val === undefined) {
if (val === '' || val === '.') {
thisValue = null
} else {
const entries = val
Expand All @@ -112,7 +111,7 @@ export default class VCF {

const valueType = this.getMetadata(
'FORMAT',
formatKeys[index],
formatKeys[index]!,
'Type',
)
if (valueType === 'Integer' || valueType === 'Float') {
Expand All @@ -122,7 +121,7 @@ export default class VCF {
}
}

genotypes[sample][formatKeys[index]] = thisValue
genotypes[sample][formatKeys[index]!] = thisValue
}, {})
})
}
Expand All @@ -136,20 +135,21 @@ export default class VCF {
* newlines.
*/
_parseMetadata(line: string) {
const match = line.trim().match(/^##(.+?)=(.*)/)
const match = /^##(.+?)=(.*)/.exec(line.trim())
if (!match) {
throw new Error(`Line is not a valid metadata line: ${line}`)
}
const [metaKey, metaVal] = match.slice(1, 3)

if (metaVal.startsWith('<')) {
if (!(metaKey in this.metadata)) {
this.metadata[metaKey] = {}
const r = metaKey!
if (metaVal?.startsWith('<')) {
if (!(r in this.metadata)) {
this.metadata[metaKey!] = {}
}
const [id, keyVals] = this._parseStructuredMetaVal(metaVal)
this.metadata[metaKey][id] = keyVals
this.metadata[r][id] = keyVals
} else {
this.metadata[metaKey] = metaVal
this.metadata[r] = metaVal
}
}

Expand Down Expand Up @@ -276,16 +276,16 @@ export default class VCF {
break
}
}
const fields = line.substr(0, currChar).split('\t')
const rest = line.substr(currChar + 1)
const fields = line.slice(0, currChar).split('\t')
const rest = line.slice(currChar + 1)
const [CHROM, POS, ID, REF, ALT, QUAL, FILTER] = fields
const chrom = CHROM
const pos = +POS
const id = ID === '.' ? null : ID.split(';')
const pos = +POS!
const id = ID === '.' ? null : ID!.split(';')
const ref = REF
const alt = ALT === '.' ? null : ALT.split(',')
const qual = QUAL === '.' ? null : +QUAL
const filter = FILTER === '.' ? null : FILTER.split(';')
const alt = ALT === '.' ? null : ALT!.split(',')
const qual = QUAL === '.' ? null : +QUAL!
const filter = FILTER === '.' ? null : FILTER!.split(';')

if (this.strict && fields[7] === undefined) {
throw new Error(
Expand All @@ -311,7 +311,7 @@ export default class VCF {
const itemType = this.getMetadata('INFO', key, 'Type')
if (itemType) {
if (itemType === 'Integer' || itemType === 'Float') {
items = items.map((val: string) => {
items = items.map((val: string | null) => {
if (val === null) {
return null
}
Expand Down
Loading

0 comments on commit 19dc43f

Please sign in to comment.