Skip to content

Commit

Permalink
refactor(lib): toRelativeSpecifier
Browse files Browse the repository at this point in the history
- check if `url` is inside of `parent` directory

Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Dec 20, 2024
1 parent 341e0d3 commit 2f77c6e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 30 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"prepublishOnly": "toggle-scripts -prepack",
"release": "bash ./scripts/release.sh",
"remark": "remark .",
"test": "cross-env NODE_OPTIONS=\"--conditions mlly --experimental-strip-types --experimental-transform-types\" vitest run",
"test": "yarn clean:build; cross-env NODE_OPTIONS=\"--conditions mlly --experimental-strip-types --experimental-transform-types\" vitest run",
"test:cov": "yarn test --coverage",
"test:cov:reports": "yarn test:cov --merge-reports --mode=reports",
"test:cov:ui": "yarn test:ui --coverage",
Expand Down
9 changes: 0 additions & 9 deletions src/lib/__snapshots__/to-relative-specifier.snap

This file was deleted.

31 changes: 24 additions & 7 deletions src/lib/__tests__/to-relative-specifier.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,35 @@
*/

import testSubject from '#lib/to-relative-specifier'
import type { ModuleId } from '@flex-development/mlly'
import pathe from '@flex-development/pathe'

describe('unit:lib/toRelativeSpecifier', () => {
it.each<Parameters<typeof testSubject>>([
it.each<[...Parameters<typeof testSubject>, (ModuleId)?]>([
[import.meta.url, import.meta.url],
[
pathe.pathToFileURL('__fixtures__/conditions.mts'),
pathe.pathToFileURL('src/lib/__tests__/resolver.spec.mts')
],
[
pathe.pathToFileURL('src/lib'),
pathe.pathToFileURL('src/lib/resolve-alias.mts')
pathe.pathToFileURL('src/lib/to-relative-specifier.mts'),
pathe.pathToFileURL('src/lib/')
],
[
pathe.pathToFileURL('src/lib/to-relative-specifier.mts'),
pathe.pathToFileURL('src/lib/index.mts')
],
[pathe.pathToFileURL('src/lib/cwd'), pathe.pathToFileURL('src/lib')],
[pathe.pathToFileURL('src/lib/to-relative-specifier'), import.meta.url],
[pathe.pathToFileURL('src/utils'), pathe.pathToFileURL('src/utils')]
])('should return relative specifier (%#)', (url, parent) => {
expect(testSubject(url, parent)).toMatchSnapshot()
[pathe.pathToFileURL('src/lib/to-relative-specifier.mts'), import.meta.url],
[
pathe.pathToFileURL('src/lib/to-relative-specifier.mts'),
pathe.pathToFileURL('src/lib/')
]
])('should return relative specifier (%#)', (url, parent, expected = url) => {
// Act
const result = testSubject(url, parent)

// Expect
expect(String(new URL(result, parent))).to.eq(String(expected))
})
})
43 changes: 30 additions & 13 deletions src/lib/to-relative-specifier.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* @module mlly/lib/toRelativeSpecifier
*/

import toUrl from '#lib/to-url'
import type { ModuleId } from '@flex-development/mlly'
import pathe from '@flex-development/pathe'
import { ok } from 'devlop'

/**
* Turn `url` into a *relative specifier*.
Expand All @@ -26,24 +26,41 @@ import pathe from '@flex-development/pathe'
* Relative specifier
*/
function toRelativeSpecifier(url: ModuleId, parent: ModuleId): string {
parent = pathe.fileURLToPath(parent)
url = pathe.fileURLToPath(url)

/**
* Directory name of {@linkcode parent} path.
*
* @const {string} dirname
*/
const dirname: string = pathe.dirname(parent)

/**
* Relative specifier.
*
* @var {string} specifier
*/
let specifier: string = pathe.relative(
pathe.fileURLToPath(toUrl(parent)),
pathe.fileURLToPath(toUrl(url))
)

if (/(?:\.\.\/){2,}/.test(specifier)) {
specifier = specifier.slice(specifier.indexOf(pathe.sep) + 1)
} else if (specifier.startsWith(pathe.dot.repeat(2))) {
specifier = specifier.slice(1)
} else if (specifier) {
specifier = pathe.dot + pathe.sep + specifier
let specifier: string

if (url.startsWith(parent) && parent.endsWith(pathe.sep)) {
// url is inside same directory as parent
specifier = pathe.dot + pathe.sep + url.slice(parent.length)
} else if (url === dirname || url.startsWith(dirname + pathe.sep)) {
// url is directory name of parent or inside same directory as parent
specifier = pathe.dot + pathe.sep + url.slice(dirname.length + 1)
} else {
specifier = pathe.dot
// url is outside directory of parent
specifier = pathe.relative(parent, url)
ok(specifier.startsWith(pathe.dot), 'expected result to start with "."')

if (specifier !== pathe.dot && specifier !== pathe.dot.repeat(2)) {
if (/(?:\.\.\/){2,}/.test(specifier)) {
// remove first '../' segment:
// pathe.relative backs out of an extra directory
specifier = specifier.slice(specifier.indexOf(pathe.sep) + 1)
}
}
}

return specifier
Expand Down

0 comments on commit 2f77c6e

Please sign in to comment.