Skip to content

Commit

Permalink
feat(utils): normalizeModuleResolution
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Feb 6, 2023
1 parent b0f8188 commit 2d8d082
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintrc.base.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,7 @@ const config = {
'@typescript-eslint/no-base-to-string': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-unused-expressions': 0,
'@typescript-eslint/prefer-ts-expect-error': 0,
'@typescript-eslint/restrict-template-expressions': 0,
'@typescript-eslint/unbound-method': 0,
'chai-expect/missing-assertion': 2,
Expand Down
52 changes: 52 additions & 0 deletions src/utils/__tests__/normalize-module-resolution.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @file Unit Tests - normalizeModuleResolution
* @module tsconfig-utils/utils/tests/unit/normalizeModuleResolution
*/

import { ModuleResolutionKind } from '@flex-development/tsconfig-types'
import ts from 'typescript'
import testSubject from '../normalize-module-resolution'

describe('unit:utils/normalizeModuleResolution', () => {
it('should return normalized compiler option', () => {
// Arrange
const cases: [
...Parameters<typeof testSubject>,
ts.ModuleResolutionKind
][] = [
// @ts-ignore ts(2551)
['Bundler', ts.ModuleResolutionKind.Bundler],
['Classic', ts.ModuleResolutionKind.Classic],
['Node', ts.ModuleResolutionKind.NodeJs],
// @ts-ignore ts(2551)
['Node10', ts.ModuleResolutionKind.Node10],
['Node16', ts.ModuleResolutionKind.Node16],
['NodeNext', ts.ModuleResolutionKind.NodeNext],
// @ts-ignore ts(2551)
[ModuleResolutionKind.Bundler, ts.ModuleResolutionKind.Bundler],
[ModuleResolutionKind.Classic, ts.ModuleResolutionKind.Classic],
// @ts-ignore ts(2551)
[ModuleResolutionKind.Node10, ts.ModuleResolutionKind.Node10],
[ModuleResolutionKind.Node16, ts.ModuleResolutionKind.Node16],
[ModuleResolutionKind.NodeJs, ts.ModuleResolutionKind.NodeJs],
[ModuleResolutionKind.NodeNext, ts.ModuleResolutionKind.NodeNext],
// @ts-ignore ts(2551)
[ts.ModuleResolutionKind.Bundler, ts.ModuleResolutionKind.Bundler],
[ts.ModuleResolutionKind.Classic, ts.ModuleResolutionKind.Classic],
// @ts-ignore ts(2551)
[ts.ModuleResolutionKind.Node10, ts.ModuleResolutionKind.Node10],
[ts.ModuleResolutionKind.Node16, ts.ModuleResolutionKind.Node16],
[ts.ModuleResolutionKind.NodeJs, ts.ModuleResolutionKind.NodeJs],
[ts.ModuleResolutionKind.NodeNext, ts.ModuleResolutionKind.NodeNext]
]

// Act + Expect
cases.forEach(([option, expected]) => {
expect(testSubject(option)).to.equal(expected)
})
})

it('should return undefined if option cannot be normalized', () => {
expect(testSubject(faker.string.sample())).to.be.undefined
})
})
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { default as normalizeJsx } from './normalize-jsx'
export { default as normalizeLib } from './normalize-lib'
export { default as normalizeModule } from './normalize-module'
export { default as normalizeModuleDetection } from './normalize-module-detection'
export { default as normalizeModuleResolution } from './normalize-module-resolution'
72 changes: 72 additions & 0 deletions src/utils/normalize-module-resolution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @file Utilities - normalizeModuleResolution
* @module tsconfig-utils/utils/normalizeModuleResolution
*/

import { getPropertyValue } from '#src/internal'
import { ModuleResolutionKind } from '@flex-development/tsconfig-types'
import { isString } from '@flex-development/tutils'
import ts from 'typescript'

/**
* Converts the given `option` to a **programmatic** [`moduleResolution`][1]
* option.
*
* TypeScript programs expect a {@linkcode ts.ModuleResolutionKind} value.
*
* If the `option` is already programmatic, it will be returned unmodified. If
* it cannot be converted, `undefined` will be returned instead.
*
* [1]: https://www.typescriptlang.org/tsconfig#moduleResolution
*
* @param {unknown} option - Option to evaluate
* @return {ts.ModuleResolutionKind | undefined} `ts.ModuleResolutionKind` value
* or `undefined`
*/
const normalizeModuleResolution = (
option: unknown
): ts.ModuleResolutionKind | undefined => {
// lowercase user option if it is a string
if (isString(option)) option = option.toLowerCase()

/**
* TypeScript program compiler option value, if any.
*
* @var {ts.ModuleResolutionKind | undefined} ret
*/
let ret: ts.ModuleResolutionKind | undefined

// normalize user compiler option
switch (option as ModuleResolutionKind | ts.ModuleResolutionKind) {
case ModuleResolutionKind.Bundler:
case getPropertyValue(ts.ModuleResolutionKind, 'Bundler'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'Bundler') as typeof ret
break
case ModuleResolutionKind.Classic:
case getPropertyValue(ts.ModuleResolutionKind, 'Classic'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'Classic')
break
case ModuleResolutionKind.Node10:
case getPropertyValue(ts.ModuleResolutionKind, 'Node10'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'Node10') as typeof ret
break
case ModuleResolutionKind.Node16:
case getPropertyValue(ts.ModuleResolutionKind, 'Node16'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'Node16')
break
case ModuleResolutionKind.NodeJs:
case getPropertyValue(ts.ModuleResolutionKind, 'NodeJs'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'NodeJs')
break
case ModuleResolutionKind.NodeNext:
case getPropertyValue(ts.ModuleResolutionKind, 'NodeNext'):
ret = getPropertyValue(ts.ModuleResolutionKind, 'NodeNext')
break
default:
break
}

return ret
}

export default normalizeModuleResolution

0 comments on commit 2d8d082

Please sign in to comment.