-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(utils):
normalizeCompilerOptions
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
- Loading branch information
1 parent
fd394d8
commit 1714d5b
Showing
3 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* @file Unit Tests - normalizeCompilerOptions | ||
* @module tsconfig-utils/utils/tests/unit/normalizeCompilerOptions | ||
*/ | ||
|
||
import { | ||
ImportsNotUsedKind, | ||
JsxEmit, | ||
ModuleDetectionKind, | ||
ModuleKind, | ||
ModuleResolutionKind, | ||
NewLineKind, | ||
ScriptTarget, | ||
type CompilerOptions | ||
} from '@flex-development/tsconfig-types' | ||
import ts from 'typescript' | ||
import LIB from '../lib' | ||
import testSubject from '../normalize-compiler-options' | ||
|
||
describe('unit:utils/normalizeCompilerOptions', () => { | ||
it('should return empty object if compilerOptions schema is invalid', () => { | ||
// Arrange | ||
const cases: Parameters<typeof testSubject>[] = [ | ||
[faker.datatype.array()], | ||
[faker.string.sample()] | ||
] | ||
|
||
// Act + Expect | ||
cases.forEach(([compilerOptions]) => { | ||
expect(testSubject(compilerOptions)).to.deep.equal({}) | ||
}) | ||
}) | ||
|
||
it('should return normalized compiler options', () => { | ||
// Arrange | ||
const compilerOptions: CompilerOptions = { | ||
allowJs: true, | ||
allowUnreachableCode: false, | ||
alwaysStrict: false, | ||
baseUrl: '.', | ||
checkJs: false, | ||
declaration: true, | ||
declarationMap: true, | ||
emitDecoratorMetadata: true, | ||
esModuleInterop: true, | ||
exactOptionalPropertyTypes: true, | ||
experimentalDecorators: true, | ||
forceConsistentCasingInFileNames: true, | ||
importsNotUsedAsValues: ImportsNotUsedKind.Error, | ||
isolatedModules: true, | ||
jsx: JsxEmit.ReactJSX, | ||
lib: ['dom', 'dom.iterable', 'es2020'], | ||
module: ModuleKind.ESNext, | ||
moduleDetection: ModuleDetectionKind.Force, | ||
moduleResolution: ModuleResolutionKind.NodeNext, | ||
newLine: NewLineKind.LineFeed, | ||
noEmit: true, | ||
noErrorTruncation: true, | ||
noFallthroughCasesInSwitch: true, | ||
noImplicitAny: true, | ||
noImplicitOverride: true, | ||
noImplicitReturns: true, | ||
noUncheckedIndexedAccess: true, | ||
noUnusedLocals: false, | ||
noUnusedParameters: false, | ||
outDir: 'dist', | ||
paths: { | ||
'#fixtures/*': ['__fixtures__/*'], | ||
'#src': ['src/index'], | ||
'#src/*': ['src/*'], | ||
'#tests/*': ['__tests__/*'] | ||
}, | ||
preserveConstEnums: true, | ||
preserveSymlinks: true, | ||
pretty: true, | ||
resolveJsonModule: true, | ||
rootDir: '.', | ||
skipLibCheck: true, | ||
sourceMap: true, | ||
strict: true, | ||
strictNullChecks: true, | ||
strictPropertyInitialization: true, | ||
target: ScriptTarget.ESNext, | ||
useDefineForClassFields: true, | ||
useUnknownInCatchVariables: true | ||
} | ||
|
||
// Act + Expect | ||
expect(testSubject({ ...compilerOptions, faker })).to.deep.equal({ | ||
...compilerOptions, | ||
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Error, | ||
jsx: ts.JsxEmit.ReactJSX, | ||
lib: [LIB.get('dom'), LIB.get('dom.iterable'), LIB.get('es2020')], | ||
module: ts.ModuleKind.ESNext, | ||
moduleDetection: ts.ModuleDetectionKind.Force, | ||
moduleResolution: ts.ModuleResolutionKind.NodeNext, | ||
newLine: ts.NewLineKind.LineFeed, | ||
target: ts.ScriptTarget.ESNext | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/** | ||
* @file Utilities - normalizeCompilerOptions | ||
* @module tsconfig-utils/utils/normalizeCompilerOptions | ||
*/ | ||
|
||
import type { | ||
CompilerOptions, | ||
CompilerOptionsValue | ||
} from '@flex-development/tsconfig-types' | ||
import { isNIL, isPrimitive, type Nilable } from '@flex-development/tutils' | ||
import sortKeys from 'sort-keys' | ||
import type ts from 'typescript' | ||
import COMPILER_OPTIONS from './compiler-options' | ||
import normalizeImportsNotUsed from './normalize-imports-not-used' | ||
import normalizeJsx from './normalize-jsx' | ||
import normalizeLib from './normalize-lib' | ||
import normalizeModule from './normalize-module' | ||
import normalizeModuleDetection from './normalize-module-detection' | ||
import normalizeModuleResolution from './normalize-module-resolution' | ||
import normalizeNewLine from './normalize-new-line' | ||
import normalizeTarget from './normalize-target' | ||
|
||
/** | ||
* Converts the given user [`compilerOptions`][1] into **programmatic** compiler | ||
* options. | ||
* | ||
* The TypeScript program expects `compilerOptions` to use enum values where | ||
* appropriate. | ||
* | ||
* [1]: https://www.typescriptlang.org/tsconfig#compilerOptions | ||
* | ||
* @param {unknown} compilerOptions - User compiler options | ||
* @return {ts.CompilerOptions} TypeScript program compiler options | ||
*/ | ||
const normalizeCompilerOptions = ( | ||
compilerOptions: unknown | ||
): ts.CompilerOptions => { | ||
// exit early if compilerOptions schema is invalid | ||
if (Array.isArray(compilerOptions) || isPrimitive(compilerOptions)) return {} | ||
|
||
/** | ||
* TypeScript program compiler options. | ||
* | ||
* @const {ts.CompilerOptions} ret | ||
*/ | ||
const ret: ts.CompilerOptions = {} | ||
|
||
/** | ||
* Sets a compiler option on {@linkcode ret}. | ||
* | ||
* Does nothing if the given `value` is `null` or `undefined`. | ||
* | ||
* @param {keyof ts.CompilerOptions} option - Compiler option name | ||
* @param {Nilable<CompilerOptionsValue>} value - Compiler option value | ||
* @return {void} Nothing when complete | ||
*/ | ||
const set = ( | ||
option: keyof ts.CompilerOptions, | ||
value: Nilable<CompilerOptionsValue> | ||
): void => void (!isNIL(value) && (ret[option] = value)) | ||
|
||
// get programmatic options | ||
for (const [key, val] of Object.entries(compilerOptions as CompilerOptions)) { | ||
switch (key) { | ||
case 'importsNotUsedAsValues': | ||
set(key, normalizeImportsNotUsed(val)) | ||
break | ||
case 'jsx': | ||
set(key, normalizeJsx(val)) | ||
break | ||
case 'lib': | ||
set(key, normalizeLib(val)) | ||
break | ||
case 'module': | ||
set(key, normalizeModule(val)) | ||
break | ||
case 'moduleDetection': | ||
set(key, normalizeModuleDetection(val)) | ||
break | ||
case 'moduleResolution': | ||
set(key, normalizeModuleResolution(val)) | ||
break | ||
case 'newLine': | ||
set(key, normalizeNewLine(val)) | ||
break | ||
case 'target': | ||
set(key, normalizeTarget(val)) | ||
break | ||
default: | ||
COMPILER_OPTIONS.has(key) && set(key, val) | ||
break | ||
} | ||
} | ||
|
||
return sortKeys(ret, { deep: true }) | ||
} | ||
|
||
export default normalizeCompilerOptions |