@flex-development/mlly 1.0.0-alpha.16 → 1.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.mjs.map +4 -5
- package/dist/internal/dequote.mjs +1 -0
- package/dist/internal/dequote.mjs.map +8 -0
- package/dist/internal/format-type-map.mjs +1 -0
- package/dist/internal/format-type-map.mjs.map +8 -0
- package/dist/internal/get-specifier-kind.mjs +1 -0
- package/dist/internal/get-specifier-kind.mjs.map +8 -0
- package/dist/internal/get-subpaths.mjs +1 -0
- package/dist/internal/get-subpaths.mjs.map +8 -0
- package/dist/internal/regex-encoded-sep.mjs +1 -0
- package/dist/internal/regex-encoded-sep.mjs.map +8 -0
- package/dist/internal/regex-internal-specifier.mjs +1 -0
- package/dist/internal/regex-internal-specifier.mjs.map +8 -0
- package/dist/internal/regex-invalid-segment.mjs +1 -0
- package/dist/internal/regex-invalid-segment.mjs.map +8 -0
- package/dist/internal/regex-package-name.mjs +1 -0
- package/dist/internal/regex-package-name.mjs.map +8 -0
- package/dist/internal/regex-package-path.mjs +1 -0
- package/dist/internal/regex-package-path.mjs.map +8 -0
- package/dist/internal/resolver.mjs +1 -0
- package/dist/internal/resolver.mjs.map +8 -0
- package/dist/internal/validate-array-set.mjs +1 -0
- package/dist/internal/validate-array-set.mjs.map +8 -0
- package/dist/internal/validate-boolean.mjs +1 -0
- package/dist/internal/validate-boolean.mjs.map +8 -0
- package/dist/internal/validate-map.mjs +1 -0
- package/dist/internal/validate-map.mjs.map +8 -0
- package/dist/internal/validate-object.mjs +1 -0
- package/dist/internal/validate-object.mjs.map +8 -0
- package/dist/internal/validate-set.mjs +1 -0
- package/dist/internal/validate-set.mjs.map +8 -0
- package/dist/internal/validate-string.mjs +1 -0
- package/dist/internal/validate-string.mjs.map +8 -0
- package/dist/internal/validate-url-string.mjs +1 -0
- package/dist/internal/validate-url-string.mjs.map +8 -0
- package/dist/utils/compare-subpaths.mjs.map +4 -5
- package/dist/utils/conditions.mjs.map +4 -5
- package/dist/utils/detect-syntax.mjs.map +4 -5
- package/dist/utils/extension-format-map.mjs.map +4 -5
- package/dist/utils/extract-statements.mjs.map +4 -5
- package/dist/utils/fill-modules.mjs.map +5 -8
- package/dist/utils/find-dynamic-imports.mjs.map +5 -8
- package/dist/utils/find-exports.mjs.map +5 -8
- package/dist/utils/find-requires.mjs.map +5 -8
- package/dist/utils/find-static-imports.mjs.map +5 -8
- package/dist/utils/find-subpath.mjs.map +5 -9
- package/dist/utils/get-format.mjs.map +5 -8
- package/dist/utils/get-source.mjs.map +4 -5
- package/dist/utils/has-cjs-syntax.mjs.map +4 -5
- package/dist/utils/has-esm-syntax.mjs.map +4 -5
- package/dist/utils/index.mjs.map +5 -8
- package/dist/utils/is-absolute-specifier.mjs.map +4 -5
- package/dist/utils/is-bare-specifier.mjs.map +4 -5
- package/dist/utils/is-directory.mjs.map +4 -5
- package/dist/utils/is-exports-sugar.mjs.map +4 -5
- package/dist/utils/is-file.mjs.map +4 -5
- package/dist/utils/is-relative-specifier.mjs.map +4 -5
- package/dist/utils/lookup-package-scope.mjs.map +4 -5
- package/dist/utils/parse-data-url.mjs.map +4 -5
- package/dist/utils/parse-module-id.mjs.map +5 -9
- package/dist/utils/parse-subpath.mjs.map +5 -8
- package/dist/utils/pattern-character.mjs.map +4 -5
- package/dist/utils/read-package-json.mjs.map +4 -5
- package/dist/utils/resolve-alias.mjs.map +5 -9
- package/dist/utils/resolve-aliases.mjs.map +4 -5
- package/dist/utils/resolve-extensions.mjs.map +4 -5
- package/dist/utils/resolve-module.mjs.map +4 -5
- package/dist/utils/resolve-modules.mjs.map +4 -5
- package/dist/utils/to-absolute-specifier.mjs.map +4 -5
- package/dist/utils/to-bare-specifier.mjs.map +4 -5
- package/dist/utils/to-data-url.mjs.map +4 -5
- package/dist/utils/to-node-url.mjs.map +4 -5
- package/dist/utils/to-relative-specifier.mjs.map +4 -5
- package/dist/utils/to-url.mjs.map +4 -5
- package/dist/utils/validate-assertions.mjs.map +5 -8
- package/dist/utils/validate-exports.mjs.map +4 -5
- package/package.json +8 -9
- package/src/enums/assert-type.ts +0 -23
- package/src/enums/format.ts +0 -19
- package/src/enums/index.ts +0 -11
- package/src/enums/kind-specifier-syntax.ts +0 -16
- package/src/enums/kind-specifier.ts +0 -19
- package/src/enums/kind-statement-syntax.ts +0 -24
- package/src/enums/kind-statement.ts +0 -17
- package/src/index.ts +0 -9
- package/src/interfaces/import-assertions.ts +0 -24
- package/src/interfaces/import-dynamic.ts +0 -46
- package/src/interfaces/import-static.ts +0 -46
- package/src/interfaces/index.ts +0 -25
- package/src/interfaces/options-fill-module.ts +0 -26
- package/src/interfaces/options-find-subpath.ts +0 -57
- package/src/interfaces/options-get-format.ts +0 -80
- package/src/interfaces/options-get-source.ts +0 -59
- package/src/interfaces/options-parse-module-id.ts +0 -39
- package/src/interfaces/options-parse-subpath.ts +0 -57
- package/src/interfaces/options-resolve-alias.ts +0 -59
- package/src/interfaces/options-resolve-module.ts +0 -72
- package/src/interfaces/options-resolve.ts +0 -17
- package/src/interfaces/package-scope.ts +0 -30
- package/src/interfaces/parsed-data-url.ts +0 -63
- package/src/interfaces/parsed-module-id.ts +0 -90
- package/src/interfaces/parsed-subpath.ts +0 -56
- package/src/interfaces/statement-export.ts +0 -52
- package/src/interfaces/statement-import.ts +0 -45
- package/src/interfaces/statement-require.ts +0 -45
- package/src/interfaces/statement.ts +0 -64
- package/src/internal/dequote.ts +0 -18
- package/src/internal/format-type-map.ts +0 -28
- package/src/internal/get-specifier-kind.ts +0 -41
- package/src/internal/get-subpaths.ts +0 -43
- package/src/internal/regex-encoded-sep.ts +0 -17
- package/src/internal/regex-internal-specifier.ts +0 -19
- package/src/internal/regex-invalid-segment.ts +0 -25
- package/src/internal/regex-package-name.ts +0 -18
- package/src/internal/regex-package-path.ts +0 -20
- package/src/internal/resolver.ts +0 -790
- package/src/internal/validate-array-set.ts +0 -35
- package/src/internal/validate-boolean.ts +0 -30
- package/src/internal/validate-map.ts +0 -36
- package/src/internal/validate-object.ts +0 -30
- package/src/internal/validate-set.ts +0 -32
- package/src/internal/validate-string.ts +0 -31
- package/src/internal/validate-url-string.ts +0 -34
- package/src/types/declaration.ts +0 -22
- package/src/types/fn-change-ext.ts +0 -33
- package/src/types/index.ts +0 -14
- package/src/types/mime-type.ts +0 -19
- package/src/types/module-id.ts +0 -15
- package/src/types/module-specifier-type.ts +0 -13
- package/src/types/protocol.ts +0 -40
- package/src/types/syntax-kind-export.ts +0 -20
- package/src/types/syntax-kind-import.ts +0 -22
- package/src/types/syntax-kind-require.ts +0 -15
- package/src/utils/compare-subpaths.ts +0 -100
- package/src/utils/conditions.ts +0 -15
- package/src/utils/detect-syntax.ts +0 -40
- package/src/utils/extension-format-map.ts +0 -34
- package/src/utils/extract-statements.ts +0 -46
- package/src/utils/fill-modules.ts +0 -133
- package/src/utils/find-dynamic-imports.ts +0 -75
- package/src/utils/find-exports.ts +0 -156
- package/src/utils/find-requires.ts +0 -75
- package/src/utils/find-static-imports.ts +0 -86
- package/src/utils/find-subpath.ts +0 -251
- package/src/utils/get-format.ts +0 -249
- package/src/utils/get-source.ts +0 -144
- package/src/utils/has-cjs-syntax.ts +0 -44
- package/src/utils/has-esm-syntax.ts +0 -40
- package/src/utils/index.ts +0 -45
- package/src/utils/is-absolute-specifier.ts +0 -53
- package/src/utils/is-bare-specifier.ts +0 -36
- package/src/utils/is-directory.ts +0 -25
- package/src/utils/is-exports-sugar.ts +0 -81
- package/src/utils/is-file.ts +0 -25
- package/src/utils/is-relative-specifier.ts +0 -34
- package/src/utils/lookup-package-scope.ts +0 -97
- package/src/utils/parse-data-url.ts +0 -71
- package/src/utils/parse-module-id.ts +0 -197
- package/src/utils/parse-subpath.ts +0 -331
- package/src/utils/pattern-character.ts +0 -13
- package/src/utils/read-package-json.ts +0 -113
- package/src/utils/resolve-alias.ts +0 -224
- package/src/utils/resolve-aliases.ts +0 -58
- package/src/utils/resolve-extensions.ts +0 -33
- package/src/utils/resolve-module.ts +0 -181
- package/src/utils/resolve-modules.ts +0 -60
- package/src/utils/to-absolute-specifier.ts +0 -30
- package/src/utils/to-bare-specifier.ts +0 -211
- package/src/utils/to-data-url.ts +0 -42
- package/src/utils/to-node-url.ts +0 -27
- package/src/utils/to-relative-specifier.ts +0 -55
- package/src/utils/to-url.ts +0 -30
- package/src/utils/validate-assertions.ts +0 -126
- package/src/utils/validate-exports.ts +0 -131
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file resolveAlias
|
|
3
|
-
* @module mlly/utils/resolveAlias
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ParsedModuleId, ResolveAliasOptions } from '#src/interfaces'
|
|
7
|
-
import validateArraySet from '#src/internal/validate-array-set'
|
|
8
|
-
import validateBoolean from '#src/internal/validate-boolean'
|
|
9
|
-
import validateObject from '#src/internal/validate-object'
|
|
10
|
-
import validateString from '#src/internal/validate-string'
|
|
11
|
-
import validateURLString from '#src/internal/validate-url-string'
|
|
12
|
-
import type { NodeError } from '@flex-development/errnode'
|
|
13
|
-
import pathe from '@flex-development/pathe'
|
|
14
|
-
import {
|
|
15
|
-
CompareResult,
|
|
16
|
-
DOT,
|
|
17
|
-
flat,
|
|
18
|
-
get,
|
|
19
|
-
includes,
|
|
20
|
-
isNIL,
|
|
21
|
-
isNull,
|
|
22
|
-
keys,
|
|
23
|
-
regexp,
|
|
24
|
-
sort,
|
|
25
|
-
type Nullable
|
|
26
|
-
} from '@flex-development/tutils'
|
|
27
|
-
import { URL, pathToFileURL } from 'node:url'
|
|
28
|
-
import compareSubpaths from './compare-subpaths'
|
|
29
|
-
import CONDITIONS from './conditions'
|
|
30
|
-
import parseModuleId from './parse-module-id'
|
|
31
|
-
import PATTERN_CHARACTER from './pattern-character'
|
|
32
|
-
import RESOLVE_EXTENSIONS from './resolve-extensions'
|
|
33
|
-
import resolveModule from './resolve-module'
|
|
34
|
-
import toBareSpecifier from './to-bare-specifier'
|
|
35
|
-
import toRelativeSpecifier from './to-relative-specifier'
|
|
36
|
-
import toURL from './to-url'
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Resolves a path alias in the given module `specifier`; does nothing if a path
|
|
40
|
-
* match isn't found.
|
|
41
|
-
*
|
|
42
|
-
* @see {@linkcode ResolveAliasOptions}
|
|
43
|
-
*
|
|
44
|
-
* @async
|
|
45
|
-
*
|
|
46
|
-
* @param {string} specifier - Module specifier to evaluate
|
|
47
|
-
* @param {ResolveAliasOptions} [options={}] - Resolution options
|
|
48
|
-
* @return {Promise<string>} Resolved specifier or original module specifier
|
|
49
|
-
* @throws {NodeError}
|
|
50
|
-
*/
|
|
51
|
-
const resolveAlias = async (
|
|
52
|
-
specifier: string,
|
|
53
|
-
options: ResolveAliasOptions = {}
|
|
54
|
-
): Promise<string> => {
|
|
55
|
-
const {
|
|
56
|
-
absolute = true,
|
|
57
|
-
aliases = {},
|
|
58
|
-
condition = 'default',
|
|
59
|
-
conditions = CONDITIONS,
|
|
60
|
-
cwd = pathToFileURL(DOT),
|
|
61
|
-
ext,
|
|
62
|
-
extensions = RESOLVE_EXTENSIONS,
|
|
63
|
-
parent = import.meta.url,
|
|
64
|
-
preserveSymlinks = false
|
|
65
|
-
} = options
|
|
66
|
-
|
|
67
|
-
// ensure specifier is a string
|
|
68
|
-
validateString(specifier, 'specifier')
|
|
69
|
-
|
|
70
|
-
// ensure option schemas
|
|
71
|
-
validateBoolean(absolute, 'options.absolute')
|
|
72
|
-
validateObject(aliases, 'options.aliases')
|
|
73
|
-
validateString(condition, 'options.condition')
|
|
74
|
-
validateArraySet(conditions, 'options.conditions')
|
|
75
|
-
validateURLString(cwd, 'options.cwd')
|
|
76
|
-
validateArraySet(extensions, 'options.extensions')
|
|
77
|
-
validateURLString(parent, 'options.parent')
|
|
78
|
-
validateBoolean(preserveSymlinks, 'options.preserveSymlinks')
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Parsed module id.
|
|
82
|
-
*
|
|
83
|
-
* **Note**: Ensures {@linkcode specifier} is a valid module specifier.
|
|
84
|
-
*
|
|
85
|
-
* @const {ParsedModuleId} id
|
|
86
|
-
*/
|
|
87
|
-
const id: ParsedModuleId = parseModuleId(specifier, {
|
|
88
|
-
parent: toURL(parent),
|
|
89
|
-
pkgname: false
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Path alias in {@linkcode aliases} that maps to {@linkcode specifier}.
|
|
94
|
-
*
|
|
95
|
-
* @var {Nullable<string>} key
|
|
96
|
-
*/
|
|
97
|
-
let alias: Nullable<string> = null
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Everything after {@linkcode alias} in {@linkcode specifier}.
|
|
101
|
-
*
|
|
102
|
-
* @var {string} trail
|
|
103
|
-
*/
|
|
104
|
-
let trail: string = ''
|
|
105
|
-
|
|
106
|
-
// match specifier to alias
|
|
107
|
-
for (const key of sort(keys(aliases), compareSubpaths)) {
|
|
108
|
-
/**
|
|
109
|
-
* Index of {@linkcode PATTERN_CHARACTER} in {@linkcode key}.
|
|
110
|
-
*
|
|
111
|
-
* @const {number} p
|
|
112
|
-
*/
|
|
113
|
-
const pattern: number = key.indexOf(PATTERN_CHARACTER)
|
|
114
|
-
|
|
115
|
-
// no pattern character => need exact match for alias
|
|
116
|
-
if (pattern === -1 && key === id.raw) {
|
|
117
|
-
alias = key
|
|
118
|
-
break
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// pattern character => need best match for alias
|
|
122
|
-
if (pattern !== -1 && id.raw.startsWith(key.slice(0, pattern))) {
|
|
123
|
-
/**
|
|
124
|
-
* Everything after pattern character (`*`) in {@linkcode key}.
|
|
125
|
-
*
|
|
126
|
-
* @const {string} trailer
|
|
127
|
-
*/
|
|
128
|
-
const trailer: string = key.slice(pattern + 1)
|
|
129
|
-
|
|
130
|
-
// best match found => reset key and base
|
|
131
|
-
if (
|
|
132
|
-
id.raw.length >= key.length &&
|
|
133
|
-
id.raw.endsWith(trailer) &&
|
|
134
|
-
compareSubpaths(alias ?? '', key) === CompareResult.GREATER_THAN &&
|
|
135
|
-
key.lastIndexOf(PATTERN_CHARACTER) === pattern
|
|
136
|
-
) {
|
|
137
|
-
alias = key
|
|
138
|
-
trail = id.raw.slice(pattern, id.raw.length - trailer.length)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// exit early if alias was not found or alias does not map any paths
|
|
144
|
-
if (isNull(alias) || isNIL(aliases[alias])) return specifier
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* URL of directory to resolve non-absolute modules from.
|
|
148
|
-
*
|
|
149
|
-
* @const {string} base
|
|
150
|
-
*/
|
|
151
|
-
const base: string = toURL(cwd).href.replace(/\/$/, '') + pathe.sep
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Resolved module URL.
|
|
155
|
-
*
|
|
156
|
-
* @var {Nullable<URL>} url
|
|
157
|
-
*/
|
|
158
|
-
let url: Nullable<URL> = null
|
|
159
|
-
|
|
160
|
-
// try resolving path alias
|
|
161
|
-
for (let segment of flat([get(aliases, alias, [])])) {
|
|
162
|
-
// replace pattern character in segment with trail of specifier
|
|
163
|
-
if (includes(segment, PATTERN_CHARACTER)) {
|
|
164
|
-
segment = segment.replace(
|
|
165
|
-
new RegExp(`${regexp(PATTERN_CHARACTER)}$`),
|
|
166
|
-
trail
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Absolute paths to modules to try resolving.
|
|
172
|
-
*
|
|
173
|
-
* @var {Set<string>} tries
|
|
174
|
-
*/
|
|
175
|
-
let tries: Set<string> = new Set(
|
|
176
|
-
[
|
|
177
|
-
'',
|
|
178
|
-
...[...extensions].map(ext => pathe.formatExt(ext)),
|
|
179
|
-
...[...extensions].map(ext => '/index' + pathe.formatExt(ext))
|
|
180
|
-
]
|
|
181
|
-
.map((suffix: string) => segment + suffix)
|
|
182
|
-
.filter((segment: string) => !!segment.length)
|
|
183
|
-
.map((segment: string) => new URL(segment, base).pathname)
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
// add attempt to resolve possible package export
|
|
187
|
-
if (segment.startsWith('node_modules')) {
|
|
188
|
-
const [trypath = ''] = [...tries]
|
|
189
|
-
tries = new Set([trypath.replace(/.*\/node_modules\//, ''), ...tries])
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// find first resolvable module
|
|
193
|
-
for (const trypath of tries) {
|
|
194
|
-
try {
|
|
195
|
-
url = await resolveModule(trypath, {
|
|
196
|
-
condition,
|
|
197
|
-
conditions,
|
|
198
|
-
ext,
|
|
199
|
-
extensions,
|
|
200
|
-
parent: toURL(parent),
|
|
201
|
-
preserveSymlinks
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
// exit if module was resolved
|
|
205
|
-
break
|
|
206
|
-
} catch {
|
|
207
|
-
continue
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// stop checking path segments if path alias was resolved
|
|
212
|
-
if (url) break
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return url
|
|
216
|
-
? absolute
|
|
217
|
-
? url.href
|
|
218
|
-
: /\/node_modules\//.test(url.href)
|
|
219
|
-
? toBareSpecifier(url, toURL(parent), new Set(conditions))
|
|
220
|
-
: toRelativeSpecifier(url, toURL(parent))
|
|
221
|
-
: specifier
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export default resolveAlias
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file resolveAliases
|
|
3
|
-
* @module mlly/utils/resolveAliases
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { SpecifierSyntaxKind } from '#src/enums'
|
|
7
|
-
import type { ResolveAliasOptions } from '#src/interfaces'
|
|
8
|
-
import { regexp } from '@flex-development/tutils'
|
|
9
|
-
import extractStatements from './extract-statements'
|
|
10
|
-
import resolveAlias from './resolve-alias'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Resolves path aliases in the given piece of source `code`.
|
|
14
|
-
*
|
|
15
|
-
* @see {@linkcode ResolveAliasOptions}
|
|
16
|
-
* @see {@linkcode resolveAlias}
|
|
17
|
-
*
|
|
18
|
-
* @async
|
|
19
|
-
*
|
|
20
|
-
* @param {string} code - Code to evaluate
|
|
21
|
-
* @param {ResolveAliasOptions} [options={}] - Resolve alias options
|
|
22
|
-
* @return {Promise<string>} `code` unmodified or with path aliases resolved
|
|
23
|
-
*/
|
|
24
|
-
const resolveAliases = async (
|
|
25
|
-
code: string,
|
|
26
|
-
options: ResolveAliasOptions = {}
|
|
27
|
-
): Promise<string> => {
|
|
28
|
-
for (const statement of extractStatements(code)) {
|
|
29
|
-
if (statement.specifier) {
|
|
30
|
-
if (statement.specifier_syntax !== SpecifierSyntaxKind.DYNAMIC) {
|
|
31
|
-
/**
|
|
32
|
-
* Resolved module specifier.
|
|
33
|
-
*
|
|
34
|
-
* @const {string} specifier
|
|
35
|
-
*/
|
|
36
|
-
const specifier: string = await resolveAlias(
|
|
37
|
-
statement.specifier,
|
|
38
|
-
options
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
// replace path alias
|
|
42
|
-
if (specifier !== statement.specifier) {
|
|
43
|
-
code = code.replace(
|
|
44
|
-
statement.code,
|
|
45
|
-
statement.code.replace(
|
|
46
|
-
new RegExp(`(?<=["'])${regexp(statement.specifier)}(?=["'])`),
|
|
47
|
-
specifier
|
|
48
|
-
)
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return code
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export default resolveAliases
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file RESOLVE_EXTENSIONS
|
|
3
|
-
* @module mlly/utils/RESOLVE_EXTENSIONS
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Ext } from '@flex-development/pathe'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Default resolvable file extensions.
|
|
10
|
-
*
|
|
11
|
-
* @see {@linkcode Ext}
|
|
12
|
-
*
|
|
13
|
-
* @const {Set<Ext>} RESOLVE_EXTENSIONS
|
|
14
|
-
*/
|
|
15
|
-
const RESOLVE_EXTENSIONS: Set<Ext> = new Set([
|
|
16
|
-
'.mjs',
|
|
17
|
-
'.mts',
|
|
18
|
-
'.cjs',
|
|
19
|
-
'.cts',
|
|
20
|
-
'.js',
|
|
21
|
-
'.ts',
|
|
22
|
-
'.jsx',
|
|
23
|
-
'.tsx',
|
|
24
|
-
'.css',
|
|
25
|
-
'.json',
|
|
26
|
-
'.node',
|
|
27
|
-
'.wasm',
|
|
28
|
-
'.d.mts',
|
|
29
|
-
'.d.cts',
|
|
30
|
-
'.d.ts'
|
|
31
|
-
])
|
|
32
|
-
|
|
33
|
-
export default RESOLVE_EXTENSIONS
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file resolveModule
|
|
3
|
-
* @module mlly/utils/resolveModule
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ResolveModuleOptions } from '#src/interfaces'
|
|
7
|
-
import Resolver from '#src/internal/resolver'
|
|
8
|
-
import validateArraySet from '#src/internal/validate-array-set'
|
|
9
|
-
import validateBoolean from '#src/internal/validate-boolean'
|
|
10
|
-
import validateString from '#src/internal/validate-string'
|
|
11
|
-
import validateURLString from '#src/internal/validate-url-string'
|
|
12
|
-
import { ErrorCode, type NodeError } from '@flex-development/errnode'
|
|
13
|
-
import { isBuiltin } from '@flex-development/is-builtin'
|
|
14
|
-
import pathe from '@flex-development/pathe'
|
|
15
|
-
import { cast, isFunction, type Nullable } from '@flex-development/tutils'
|
|
16
|
-
import { URL, fileURLToPath } from 'node:url'
|
|
17
|
-
import CONDITIONS from './conditions'
|
|
18
|
-
import RESOLVE_EXTENSIONS from './resolve-extensions'
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Resolves `specifier` according to the [ESM Resolver algorithm][1], mostly 😉.
|
|
22
|
-
*
|
|
23
|
-
* Adds support for:
|
|
24
|
-
*
|
|
25
|
-
* - Extensionless file and directory index resolution
|
|
26
|
-
* - Replacing file extensions
|
|
27
|
-
*
|
|
28
|
-
* Other differences between Node.js:
|
|
29
|
-
*
|
|
30
|
-
* - [Subpath import][2] targets (that are strings) must be relative to the
|
|
31
|
-
* current working directory (e.g. `'./src/index.ts'`, `'./src/*.ts'`) or
|
|
32
|
-
* start with a [NPM valid package name][3]. See [`nodejs/node#40579`][4] for
|
|
33
|
-
* details.
|
|
34
|
-
*
|
|
35
|
-
* [1]: https://nodejs.org/api/esm.html#esm_resolver_algorithm
|
|
36
|
-
* [2]: https://nodejs.org/api/packages.html#subpath-imports
|
|
37
|
-
* [3]: https://regex101.com/r/BHcJfc
|
|
38
|
-
* [4]: https://github.com/nodejs/node/issues/40579
|
|
39
|
-
*
|
|
40
|
-
* @see {@linkcode NodeError}
|
|
41
|
-
* @see {@linkcode ResolveModuleOptions}
|
|
42
|
-
* @see {@linkcode URL}
|
|
43
|
-
*
|
|
44
|
-
* @async
|
|
45
|
-
*
|
|
46
|
-
* @param {string} specifier - Module specifier to resolve
|
|
47
|
-
* @param {ResolveModuleOptions} [options={}] - Module resolution options
|
|
48
|
-
* @return {Promise<URL>} Resolved module URL
|
|
49
|
-
* @throws {NodeError}
|
|
50
|
-
*/
|
|
51
|
-
const resolveModule = async (
|
|
52
|
-
specifier: string,
|
|
53
|
-
options: ResolveModuleOptions = {}
|
|
54
|
-
): Promise<URL> => {
|
|
55
|
-
const {
|
|
56
|
-
condition = 'default',
|
|
57
|
-
conditions = CONDITIONS,
|
|
58
|
-
extensions = RESOLVE_EXTENSIONS,
|
|
59
|
-
parent = import.meta.url,
|
|
60
|
-
preserveSymlinks = false
|
|
61
|
-
} = options
|
|
62
|
-
|
|
63
|
-
// ensure specifier is a string
|
|
64
|
-
validateString(specifier, 'specifier')
|
|
65
|
-
|
|
66
|
-
// ensure option schemas
|
|
67
|
-
validateString(condition, 'options.condition')
|
|
68
|
-
validateArraySet(conditions, 'options.conditions')
|
|
69
|
-
validateArraySet(extensions, 'options.extensions')
|
|
70
|
-
validateURLString(parent, 'options.parent')
|
|
71
|
-
validateBoolean(preserveSymlinks, 'options.preserveSymlinks')
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Module resolver.
|
|
75
|
-
*
|
|
76
|
-
* @const {Resolver} resolver
|
|
77
|
-
*/
|
|
78
|
-
const resolver: Resolver = new Resolver()
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Boolean indicating only module id should be tried for resolution.
|
|
82
|
-
*
|
|
83
|
-
* @const {boolean} onetry
|
|
84
|
-
*/
|
|
85
|
-
const onetry: boolean =
|
|
86
|
-
isBuiltin(specifier) ||
|
|
87
|
-
(/^\S+:/.test(specifier) && !specifier.startsWith('file:'))
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Module ids to try resolving.
|
|
91
|
-
*
|
|
92
|
-
* @const {string[]} tries
|
|
93
|
-
*/
|
|
94
|
-
const tries: string[] = onetry
|
|
95
|
-
? []
|
|
96
|
-
: [...extensions]
|
|
97
|
-
.flatMap(ext => [
|
|
98
|
-
specifier + (ext = pathe.formatExt(ext)),
|
|
99
|
-
specifier.startsWith('#') ? specifier + '/index' : '',
|
|
100
|
-
specifier + '/index' + ext
|
|
101
|
-
])
|
|
102
|
-
.filter(id => !!id.length)
|
|
103
|
-
|
|
104
|
-
// try @types resolution
|
|
105
|
-
if (!onetry) {
|
|
106
|
-
specifier.startsWith('@types')
|
|
107
|
-
? tries.unshift(specifier + '/index.d.ts')
|
|
108
|
-
: tries.unshift('@types/' + specifier + '/index.d.ts')
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ensure attempt to resolve original specifier is first
|
|
112
|
-
tries.unshift(specifier)
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Error codes to ignore when attempting to resolve {@linkcode specifier}.
|
|
116
|
-
*
|
|
117
|
-
* **Note**: If an error is thrown, it'll be reported **_after_** all module
|
|
118
|
-
* ids in {@linkcode tries} have been evaluated.
|
|
119
|
-
*
|
|
120
|
-
* @const {Set<ErrorCode>} ignore
|
|
121
|
-
*/
|
|
122
|
-
const ignore: Set<ErrorCode> = new Set<ErrorCode>([
|
|
123
|
-
ErrorCode.ERR_INVALID_MODULE_SPECIFIER,
|
|
124
|
-
ErrorCode.ERR_MODULE_NOT_FOUND,
|
|
125
|
-
ErrorCode.ERR_PACKAGE_PATH_NOT_EXPORTED,
|
|
126
|
-
ErrorCode.ERR_UNSUPPORTED_DIR_IMPORT
|
|
127
|
-
])
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Module resolution error.
|
|
131
|
-
*
|
|
132
|
-
* @var {NodeError} error
|
|
133
|
-
*/
|
|
134
|
-
let error: NodeError
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Resolved module URL.
|
|
138
|
-
*
|
|
139
|
-
* @var {Nullable<URL>} url
|
|
140
|
-
*/
|
|
141
|
-
let url: Nullable<URL> = null
|
|
142
|
-
|
|
143
|
-
// try module resolution
|
|
144
|
-
for (const id of tries) {
|
|
145
|
-
try {
|
|
146
|
-
url = resolver.resolveModule(
|
|
147
|
-
id,
|
|
148
|
-
parent,
|
|
149
|
-
condition,
|
|
150
|
-
new Set(conditions),
|
|
151
|
-
preserveSymlinks
|
|
152
|
-
)
|
|
153
|
-
} catch (e: unknown) {
|
|
154
|
-
url = null
|
|
155
|
-
if (id === specifier) error = cast(e)
|
|
156
|
-
if (!ignore.has(cast<NodeError>(e).code)) throw e
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// stop resolution attempts if module was resolved
|
|
160
|
-
if (url) break
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// throw if module was not resolved
|
|
164
|
-
if (!url) throw error!
|
|
165
|
-
|
|
166
|
-
// replace file extension
|
|
167
|
-
if (url.protocol === 'file:') {
|
|
168
|
-
let { ext } = options
|
|
169
|
-
|
|
170
|
-
// get replacement extension
|
|
171
|
-
ext = isFunction(ext) ? await ext(specifier, url) : ext
|
|
172
|
-
|
|
173
|
-
// replace file extension in url href and pathname
|
|
174
|
-
url.href = pathe.changeExt(url.href, ext).replace(/\/index$/, '')
|
|
175
|
-
url.pathname = fileURLToPath(url.href)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return url
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export default resolveModule
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file resolveModules
|
|
3
|
-
* @module mlly/utils/resolveModules
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { SpecifierSyntaxKind } from '#src/enums'
|
|
7
|
-
import type { ResolveModuleOptions } from '#src/interfaces'
|
|
8
|
-
import { regexp } from '@flex-development/tutils'
|
|
9
|
-
import type { URL } from 'node:url'
|
|
10
|
-
import extractStatements from './extract-statements'
|
|
11
|
-
import resolveModule from './resolve-module'
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Converts all module specifiers in `code` to absolute specifiers.
|
|
15
|
-
*
|
|
16
|
-
* ::: info
|
|
17
|
-
* Useful for converting code to [`data:` URLs][1].
|
|
18
|
-
* :::
|
|
19
|
-
*
|
|
20
|
-
* [1]: https://nodejs.org/api/esm.html#data-imports
|
|
21
|
-
*
|
|
22
|
-
* @see {@linkcode ResolveModuleOptions}
|
|
23
|
-
* @see https://nodejs.org/api/esm.html#terminology
|
|
24
|
-
*
|
|
25
|
-
* @async
|
|
26
|
-
*
|
|
27
|
-
* @param {string} code - Code to evaluate
|
|
28
|
-
* @param {ResolveModuleOptions} [options={}] - Module resolution options
|
|
29
|
-
* @return {Promise<string>} `code` with module specifiers fully resolved
|
|
30
|
-
*/
|
|
31
|
-
const resolveModules = async (
|
|
32
|
-
code: string,
|
|
33
|
-
options: ResolveModuleOptions = {}
|
|
34
|
-
): Promise<string> => {
|
|
35
|
-
for (const statement of extractStatements(code)) {
|
|
36
|
-
if (statement.specifier) {
|
|
37
|
-
if (statement.specifier_syntax !== SpecifierSyntaxKind.DYNAMIC) {
|
|
38
|
-
/**
|
|
39
|
-
* Resolved module URL.
|
|
40
|
-
*
|
|
41
|
-
* @const {URL} url
|
|
42
|
-
*/
|
|
43
|
-
const url: URL = await resolveModule(statement.specifier, options)
|
|
44
|
-
|
|
45
|
-
// replace original specifier
|
|
46
|
-
code = code.replace(
|
|
47
|
-
statement.code,
|
|
48
|
-
statement.code.replace(
|
|
49
|
-
new RegExp(`(?<=["'])${regexp(statement.specifier)}(?=["'])`),
|
|
50
|
-
url.href
|
|
51
|
-
)
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return code
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default resolveModules
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file toAbsoluteSpecifier
|
|
3
|
-
* @module mlly/utils/toAbsoluteSpecifier
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ModuleId } from '#src/types'
|
|
7
|
-
import { pathToFileURL } from 'node:url'
|
|
8
|
-
import toURL from './to-url'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Converts `specifier` into an absolute specifier.
|
|
12
|
-
*
|
|
13
|
-
* ::: info
|
|
14
|
-
* The absolute specifier will only include a file extension if `specifier`
|
|
15
|
-
* includes a file extension.
|
|
16
|
-
* :::
|
|
17
|
-
*
|
|
18
|
-
* @see {@linkcode ModuleId}
|
|
19
|
-
* @see https://nodejs.org/api/esm.html#terminology
|
|
20
|
-
*
|
|
21
|
-
* @param {ModuleId} specifier - Module specifier to convert
|
|
22
|
-
* @param {ModuleId} [cwd=pathToFileURL('./')] - Current working directory
|
|
23
|
-
* @return {string} `specifier` as absolute specifier (file url)
|
|
24
|
-
*/
|
|
25
|
-
const toAbsoluteSpecifier = (
|
|
26
|
-
specifier: ModuleId,
|
|
27
|
-
cwd: ModuleId = pathToFileURL('./')
|
|
28
|
-
): string => toURL(specifier, cwd).href
|
|
29
|
-
|
|
30
|
-
export default toAbsoluteSpecifier
|