Skip to content

Commit

Permalink
feat(lib): toUrl
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Nov 4, 2024
1 parent 711d283 commit ae7b2ec
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 22 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ import {
resolveModule,
resolver,
root,
toRelativeSpecifier
toRelativeSpecifier,
toUrl
} from '@flex-development/mlly'
```

Expand Down Expand Up @@ -132,6 +133,7 @@ This package exports the following identifiers:
- `packageTargetResolve`
- [`root`](./src/lib/root.mts)
- [`toRelativeSpecifier`](./src/lib/to-relative-specifier.mts)
- [`toUrl`](./src/lib/to-url.mts)

There is no default export.

Expand Down
1 change: 1 addition & 0 deletions src/__snapshots__/index.e2e.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ exports[`e2e:mlly > should expose public api 1`] = `
"resolver",
"root",
"toRelativeSpecifier",
"toUrl",
]
`;
11 changes: 11 additions & 0 deletions src/lib/__snapshots__/to-url.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`unit:lib/toUrl > should return \`id\` as \`URL\` (0) 1`] = `"node:os"`;

exports[`unit:lib/toUrl > should return \`id\` as \`URL\` (1) 1`] = `file://\${process.cwd()}/path`;

exports[`unit:lib/toUrl > should return \`id\` as \`URL\` (2) 1`] = `file://\${process.cwd()}/src/lib/__tests__/to-url.spec.mts`;

exports[`unit:lib/toUrl > should return \`id\` as \`URL\` (3) 1`] = `"node:test"`;

exports[`unit:lib/toUrl > should return \`id\` as \`URL\` (4) 1`] = `file://\${process.cwd()}/tsconfig.build.json`;
20 changes: 20 additions & 0 deletions src/lib/__tests__/to-url.spec.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @file Unit Tests - toUrl
* @module mlly/lib/tests/unit/toUrl
*/

import cwd from '#lib/cwd'
import testSubject from '#lib/to-url'
import pathe from '@flex-development/pathe'

describe('unit:lib/toUrl', () => {
it.each<Parameters<typeof testSubject>>([
['os'],
['path', cwd()],
[import.meta.url],
[new URL('node:test')],
[pathe.resolve('tsconfig.build.json')]
])('should return `id` as `URL` (%#)', (id, parent) => {
expect(testSubject(id, parent)).toMatchSnapshot()
})
})
17 changes: 2 additions & 15 deletions src/lib/get-source.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,26 @@

import fs from '#internal/fs'
import process from '#internal/process'
import canParseUrl from '#lib/can-parse-url'
import isFile from '#lib/is-file'
import toUrl from '#lib/to-url'
import {
ERR_UNSUPPORTED_ESM_URL_SCHEME,
type ErrUnsupportedEsmUrlScheme
} from '@flex-development/errnode'
import { isBuiltin } from '@flex-development/is-builtin'
import type {
GetSourceContext,
GetSourceHandler,
GetSourceOptions,
ModuleId,
Protocol
} from '@flex-development/mlly'
import pathe from '@flex-development/pathe'
import { ok } from 'devlop'

export default getSource

/**
* Get the source code for `id`.
*
* > 👉 **Note**: If `id` is not a [builtin module][builtin-module] and also
* > cannot be parsed as an {@linkcode URL}, it will be assumed to be a path and
* > converted to a [`file:` URL][file-url].
*
* [builtin-module]: https://nodejs.org/api/esm.html#builtin-modules
* [file-url]: https://nodejs.org/api/esm.html#file-urls
*
* @see {@linkcode ErrUnsupportedEsmUrlScheme}
* @see {@linkcode GetSourceOptions}
* @see {@linkcode ModuleId}
Expand Down Expand Up @@ -85,11 +76,7 @@ async function getSource(
*
* @const {URL} url
*/
const url: URL = isBuiltin(id)
? new URL('node:' + String(id).replace(/^node:/, ''))
: canParseUrl(id)
? new URL(id)
: (ok(typeof id === 'string', 'expected string'), pathe.pathToFileURL(id))
const url: URL = toUrl(id)

/**
* Source code handler for {@linkcode url}.
Expand Down
1 change: 1 addition & 0 deletions src/lib/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ export * from '#lib/resolver'
export * as resolver from '#lib/resolver'
export { default as root } from '#lib/root'
export { default as toRelativeSpecifier } from '#lib/to-relative-specifier'
export { default as toUrl } from '#lib/to-url'
5 changes: 2 additions & 3 deletions src/lib/resolver.mts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import lookupPackageScope from '#lib/lookup-package-scope'
import patternMatch from '#lib/pattern-match'
import readPackageJson from '#lib/read-package-json'
import root from '#lib/root'
import toUrl from '#lib/to-url'
import {
codes,
ERR_INVALID_MODULE_SPECIFIER,
Expand Down Expand Up @@ -672,9 +673,7 @@ async function packageResolve(
mainFields?: MainField[] | Set<MainField> | null | undefined,
fs?: FileSystem | null | undefined
): Promise<URL> {
if (isBuiltin(specifier)) {
return new URL('node:' + specifier.replace(/^node:/, ''))
}
if (isBuiltin(specifier)) return toUrl(specifier)

/**
* Index of separator in {@linkcode specifier}.
Expand Down
7 changes: 4 additions & 3 deletions src/lib/to-relative-specifier.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @module mlly/lib/toRelativeSpecifier
*/

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

Expand All @@ -20,7 +21,7 @@ import pathe from '@flex-development/pathe'
* @param {ModuleId} url
* The `file:` URL to convert
* @param {ModuleId} parent
* URL of parent module
* Parent module id
* @return {string}
* Relative specifier
*/
Expand All @@ -31,8 +32,8 @@ function toRelativeSpecifier(url: ModuleId, parent: ModuleId): string {
* @var {string} specifier
*/
let specifier: string = pathe.relative(
pathe.fileURLToPath(parent),
pathe.fileURLToPath(url)
pathe.fileURLToPath(toUrl(parent)),
pathe.fileURLToPath(toUrl(url))
)

if (/(?:\.\.\/){2,}/.test(specifier)) {
Expand Down
36 changes: 36 additions & 0 deletions src/lib/to-url.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @file toUrl
* @module mlly/lib/toUrl
*/

import canParseUrl from '#lib/can-parse-url'
import { isBuiltin } from '@flex-development/is-builtin'
import type { ModuleId } from '@flex-development/mlly'
import pathe from '@flex-development/pathe'

/**
* Convert `id` to a {@linkcode URL}.
*
* > 👉 **Note**: If `id` cannot be parsed as a `URL` (in conjunction with
* > `parent`) and is also not a [builtin module][builtin-module], it will be
* > assumed to be a path and converted to a [`file:` URL][file-url].
*
* [builtin-module]: https://nodejs.org/api/esm.html#builtin-modules
* [file-url]: https://nodejs.org/api/esm.html#file-urls
*
* @param {ModuleId} id
* The module id to convert
* @param {ModuleId | null | undefined} [parent]
* Base URL to resolve against if `id` is not absolute
* @return {URL}
* New URL
*/
function toUrl(id: ModuleId, parent?: ModuleId | null | undefined): URL {
return canParseUrl(id, parent)
? new URL(id, parent ?? undefined)
: isBuiltin(id)
? new URL('node:' + String(id))
: pathe.pathToFileURL(String(id))
}

export default toUrl

0 comments on commit ae7b2ec

Please sign in to comment.