-
-
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.
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
- Loading branch information
1 parent
13141ee
commit 8802abd
Showing
2 changed files
with
153 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,80 @@ | ||
/** | ||
* @file Functional Tests - resolveAliases | ||
* @module mkbuild/utils/tests/functional/resolveAliases | ||
*/ | ||
|
||
import path from 'node:path' | ||
import type { OutputFile, Statement } from 'src/interfaces' | ||
import { createMatchPath, loadConfig } from 'tsconfig-paths' | ||
import resolveAlias from '../resolve-alias' | ||
import testSubject from '../resolve-aliases' | ||
|
||
vi.mock('pathe') | ||
|
||
vi.mock('tsconfig-paths', async () => { | ||
type Actual = typeof import('tsconfig-paths') | ||
const path: string = 'tsconfig-paths' | ||
|
||
const { createMatchPath, loadConfig } = await vi.importActual<Actual>(path) | ||
|
||
return { | ||
createMatchPath: vi.fn(createMatchPath), | ||
loadConfig: vi.fn(loadConfig) | ||
} | ||
}) | ||
|
||
vi.mock('../resolve-alias', async () => { | ||
type Actual = typeof import('../resolve-alias') | ||
const path: string = '../resolve-alias' | ||
|
||
const { default: resolveAlias } = await vi.importActual<Actual>(path) | ||
|
||
return { default: vi.fn(resolveAlias) } | ||
}) | ||
|
||
describe('functional:utils/resolveAliases', () => { | ||
describe('noop', () => { | ||
it('should do nothing if output content is undefined', async () => { | ||
// Act | ||
await testSubject({} as OutputFile) | ||
|
||
// Expect | ||
expect(loadConfig).toHaveBeenCalledTimes(0) | ||
expect(createMatchPath).toHaveBeenCalledTimes(0) | ||
expect(resolveAlias).toHaveBeenCalledTimes(0) | ||
}) | ||
|
||
it('should do nothing if statements is empty array', async () => { | ||
// Act | ||
await testSubject({ contents: 'contents' } as OutputFile) | ||
|
||
// Expect | ||
expect(loadConfig).toHaveBeenCalledTimes(0) | ||
expect(createMatchPath).toHaveBeenCalledTimes(0) | ||
expect(resolveAlias).toHaveBeenCalledTimes(0) | ||
}) | ||
}) | ||
|
||
describe('resolve', () => { | ||
it('should resolve path aliases in output content', async () => { | ||
const statements: Pick<Statement, 'code' | 'specifier'>[] = [ | ||
{ | ||
code: "import { MODULE_EXTENSIONS } from 'src/config/constants'", | ||
specifier: 'src/config/constants' | ||
} | ||
] | ||
const output: Pick<OutputFile, 'contents' | 'src'> = { | ||
contents: statements[0]!.code, | ||
src: path.resolve('utils/resolve-alias.ts') | ||
} | ||
|
||
// Act | ||
await testSubject(output, statements) | ||
|
||
// Expect | ||
expect(loadConfig).toHaveBeenCalledTimes(1) | ||
expect(createMatchPath).toHaveBeenCalledTimes(1) | ||
expect(resolveAlias).toHaveBeenCalledTimes(statements.length) | ||
}) | ||
}) | ||
}) |
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,73 @@ | ||
/** | ||
* @file Utilities - resolveAliases | ||
* @module mkbuild/utils/resolveAliases | ||
*/ | ||
|
||
import type { BuildOptions, OutputFile, Statement } from 'src/interfaces' | ||
import type { ConfigLoaderResult, MatchPath } from 'tsconfig-paths' | ||
import resolveAlias from './resolve-alias' | ||
|
||
/** | ||
* Resolves path aliases in `output.contents`. | ||
* | ||
* @see https://github.com/dividab/tsconfig-paths | ||
* | ||
* @async | ||
* | ||
* @param {Pick<OutputFile, 'contents' | 'src'>} output - Output file object | ||
* @param {string | undefined} [output.contents] - Output file content | ||
* @param {string} output.src - Full path to source file | ||
* @param {Pick<Statement, 'code' | 'specifier'>[]} [statements=[]] - `import`, | ||
* `require`, and `export` statements in `output.contents` | ||
* @param {BuildOptions['cwd']} [cwd=process.cwd()] - Root project directory | ||
* @return {Promise<void>} Nothing when complete | ||
*/ | ||
const resolveAliases = async ( | ||
output: Pick<OutputFile, 'contents' | 'src'>, | ||
statements: Pick<Statement, 'code' | 'specifier'>[] = [], | ||
cwd: BuildOptions['cwd'] = process.cwd() | ||
): Promise<string | undefined> => { | ||
if (!output.contents || statements.length === 0) return output.contents | ||
|
||
const { createMatchPath, loadConfig } = await import('tsconfig-paths') | ||
|
||
/** | ||
* `tsconfig-paths` config loader result. | ||
* | ||
* @const {ConfigLoaderResult} tsconfig | ||
*/ | ||
const tsconfig: ConfigLoaderResult = loadConfig(cwd) | ||
|
||
if (tsconfig.resultType === 'success') { | ||
/** | ||
* Matches a path alias. | ||
* | ||
* @const {MatchPath} matcher | ||
*/ | ||
const matcher: MatchPath = createMatchPath( | ||
tsconfig.absoluteBaseUrl, | ||
tsconfig.paths, | ||
tsconfig.mainFields, | ||
tsconfig.addMatchAll | ||
) | ||
|
||
for (const statement of statements) { | ||
/** | ||
* {@link statement.code} before path alias replacement. | ||
* | ||
* @const {string} code | ||
*/ | ||
const code: string = statement.code | ||
|
||
// resolve path alias | ||
resolveAlias(statement, output.src, matcher) | ||
|
||
// replace code in output content | ||
output.contents = output.contents.replace(code, statement.code) | ||
} | ||
} | ||
|
||
return output.contents | ||
} | ||
|
||
export default resolveAliases |