@flex-development/mlly 1.0.0-alpha.1 → 1.0.0-alpha.11
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 +431 -3
- package/README.md +6 -4
- package/changelog.config.ts +404 -0
- package/dist/enums/assert-type.d.mts +21 -0
- package/dist/enums/assert-type.mjs +10 -0
- package/dist/enums/assert-type.mjs.map +6 -0
- package/dist/enums/format.d.mts +17 -0
- package/dist/enums/format.mjs +13 -0
- package/dist/enums/format.mjs.map +6 -0
- package/dist/enums/index.d.mts +10 -0
- package/dist/enums/index.mjs +15 -0
- package/dist/enums/index.mjs.map +6 -0
- package/dist/enums/kind-specifier-syntax.d.mts +14 -0
- package/dist/enums/kind-specifier-syntax.mjs +10 -0
- package/dist/enums/kind-specifier-syntax.mjs.map +6 -0
- package/dist/enums/kind-specifier.d.mts +17 -0
- package/dist/enums/kind-specifier.mjs +11 -0
- package/dist/enums/kind-specifier.mjs.map +6 -0
- package/dist/enums/kind-statement-syntax.d.mts +22 -0
- package/dist/enums/kind-statement-syntax.mjs +18 -0
- package/dist/enums/kind-statement-syntax.mjs.map +6 -0
- package/dist/enums/kind-statement.d.mts +15 -0
- package/dist/enums/kind-statement.mjs +11 -0
- package/dist/enums/kind-statement.mjs.map +6 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +6 -0
- package/dist/interfaces/import-assertions.d.mts +20 -0
- package/dist/interfaces/import-dynamic.d.mts +26 -6
- package/dist/interfaces/import-static.d.mts +22 -4
- package/dist/interfaces/index.d.mts +12 -0
- package/dist/interfaces/index.mjs +1 -0
- package/dist/interfaces/index.mjs.map +6 -0
- package/dist/interfaces/options-fill-module.d.mts +23 -0
- package/dist/interfaces/options-find-subpath.d.mts +49 -0
- package/dist/interfaces/options-get-format.d.mts +83 -0
- package/dist/interfaces/options-get-source.d.mts +63 -0
- package/dist/interfaces/options-parse-module-id.d.mts +33 -0
- package/dist/interfaces/options-parse-subpath.d.mts +31 -0
- package/dist/interfaces/options-resolve-alias.d.mts +26 -42
- package/dist/interfaces/options-resolve-module.d.mts +64 -0
- package/dist/interfaces/options-resolve.d.mts +7 -52
- package/dist/interfaces/package-scope.d.mts +25 -0
- package/dist/interfaces/parsed-data-url.d.mts +56 -0
- package/dist/interfaces/parsed-module-id.d.mts +80 -0
- package/dist/interfaces/parsed-subpath.d.mts +40 -0
- package/dist/interfaces/statement-export.d.mts +22 -9
- package/dist/interfaces/statement-import.d.mts +15 -4
- package/dist/interfaces/statement-require.d.mts +15 -4
- package/dist/interfaces/statement.d.mts +24 -8
- package/dist/internal/escape-reg-exp.d.mts +16 -0
- package/dist/internal/escape-reg-exp.mjs +10 -0
- package/dist/internal/escape-reg-exp.mjs.map +6 -0
- package/dist/internal/format-type-map.d.mts +17 -0
- package/dist/internal/format-type-map.mjs +13 -0
- package/dist/internal/format-type-map.mjs.map +6 -0
- package/dist/internal/get-specifier-kind.d.mts +17 -0
- package/dist/internal/get-specifier-kind.mjs +14 -0
- package/dist/internal/get-specifier-kind.mjs.map +6 -0
- package/dist/internal/get-subpaths.d.mts +25 -0
- package/dist/internal/get-subpaths.mjs +10 -0
- package/dist/internal/get-subpaths.mjs.map +6 -0
- package/dist/internal/is-array-index.d.mts +15 -0
- package/dist/internal/is-array-index.mjs +9 -0
- package/dist/internal/is-array-index.mjs.map +6 -0
- package/dist/internal/is-directory.d.mts +13 -0
- package/dist/internal/is-directory.mjs +16 -0
- package/dist/internal/is-directory.mjs.map +6 -0
- package/dist/internal/is-file.d.mts +13 -0
- package/dist/internal/is-file.mjs +16 -0
- package/dist/internal/is-file.mjs.map +6 -0
- package/dist/internal/is-function.d.mts +12 -0
- package/dist/internal/is-function.mjs +8 -0
- package/dist/internal/is-function.mjs.map +6 -0
- package/dist/internal/regex-encoded-sep.d.mts +13 -0
- package/dist/internal/regex-encoded-sep.mjs +6 -0
- package/dist/internal/regex-encoded-sep.mjs.map +6 -0
- package/dist/internal/regex-internal-specifier.d.mts +14 -0
- package/dist/internal/regex-internal-specifier.mjs +6 -0
- package/dist/internal/regex-internal-specifier.mjs.map +6 -0
- package/dist/internal/regex-package-name.d.mts +13 -0
- package/dist/internal/regex-package-name.mjs +6 -0
- package/dist/internal/regex-package-name.mjs.map +6 -0
- package/dist/internal/regex-package-path.d.mts +15 -0
- package/dist/internal/regex-package-path.mjs +6 -0
- package/dist/internal/regex-package-path.mjs.map +6 -0
- package/dist/internal/resolver.d.mts +130 -0
- package/dist/internal/resolver.mjs +500 -0
- package/dist/internal/resolver.mjs.map +6 -0
- package/dist/internal/validate-boolean.d.mts +20 -0
- package/dist/internal/validate-boolean.mjs +11 -0
- package/dist/internal/validate-boolean.mjs.map +6 -0
- package/dist/internal/validate-object.d.mts +23 -0
- package/dist/internal/validate-object.mjs +11 -0
- package/dist/internal/validate-object.mjs.map +6 -0
- package/dist/internal/validate-set.d.mts +23 -0
- package/dist/internal/validate-set.mjs +11 -0
- package/dist/internal/validate-set.mjs.map +6 -0
- package/dist/internal/validate-string.d.mts +20 -0
- package/dist/internal/validate-string.mjs +11 -0
- package/dist/internal/validate-string.mjs.map +6 -0
- package/dist/internal/validate-url-string.d.mts +22 -0
- package/dist/internal/validate-url-string.mjs +12 -0
- package/dist/internal/validate-url-string.mjs.map +6 -0
- package/dist/types/declaration.d.mts +1 -1
- package/dist/types/fn-change-ext.d.mts +28 -0
- package/dist/types/index.d.mts +8 -4
- package/dist/types/index.mjs +1 -0
- package/dist/types/index.mjs.map +6 -0
- package/dist/types/mime-type.d.mts +7 -5
- package/dist/types/module-id.d.mts +13 -0
- package/dist/types/module-specifier-type.d.mts +11 -0
- package/dist/types/protocol.d.mts +14 -0
- package/dist/types/syntax-kind-export.d.mts +12 -0
- package/dist/types/syntax-kind-import.d.mts +12 -0
- package/dist/types/syntax-kind-require.d.mts +12 -0
- package/dist/utils/compare-subpaths.d.mts +25 -0
- package/dist/utils/compare-subpaths.mjs +24 -0
- package/dist/utils/compare-subpaths.mjs.map +6 -0
- package/dist/utils/conditions.d.mts +13 -0
- package/dist/utils/conditions.mjs +6 -0
- package/dist/utils/conditions.mjs.map +6 -0
- package/dist/{lib → utils}/detect-syntax.d.mts +4 -4
- package/dist/{lib → utils}/detect-syntax.mjs +1 -0
- package/dist/utils/detect-syntax.mjs.map +6 -0
- package/dist/utils/extension-format-map.d.mts +16 -0
- package/dist/utils/extension-format-map.mjs +22 -0
- package/dist/utils/extension-format-map.mjs.map +6 -0
- package/dist/utils/extract-statements.d.mts +21 -0
- package/dist/{lib → utils}/extract-statements.mjs +4 -1
- package/dist/utils/extract-statements.mjs.map +6 -0
- package/dist/utils/fill-modules.d.mts +23 -0
- package/dist/utils/fill-modules.mjs +64 -0
- package/dist/utils/fill-modules.mjs.map +6 -0
- package/dist/utils/find-dynamic-imports.d.mts +18 -0
- package/dist/utils/find-dynamic-imports.mjs +39 -0
- package/dist/utils/find-dynamic-imports.mjs.map +6 -0
- package/dist/utils/find-exports.d.mts +21 -0
- package/dist/utils/find-exports.mjs +95 -0
- package/dist/utils/find-exports.mjs.map +6 -0
- package/dist/utils/find-requires.d.mts +18 -0
- package/dist/utils/find-requires.mjs +32 -0
- package/dist/utils/find-requires.mjs.map +6 -0
- package/dist/utils/find-static-imports.d.mts +18 -0
- package/dist/utils/find-static-imports.mjs +34 -0
- package/dist/utils/find-static-imports.mjs.map +6 -0
- package/dist/utils/find-subpath.d.mts +30 -0
- package/dist/utils/find-subpath.mjs +106 -0
- package/dist/utils/find-subpath.mjs.map +6 -0
- package/dist/utils/get-format.d.mts +24 -0
- package/dist/utils/get-format.mjs +111 -0
- package/dist/utils/get-format.mjs.map +6 -0
- package/dist/utils/get-source.d.mts +22 -0
- package/dist/utils/get-source.mjs +63 -0
- package/dist/utils/get-source.mjs.map +6 -0
- package/dist/{lib → utils}/has-cjs-syntax.d.mts +5 -2
- package/dist/utils/has-cjs-syntax.mjs +11 -0
- package/dist/utils/has-cjs-syntax.mjs.map +6 -0
- package/dist/{lib → utils}/has-esm-syntax.d.mts +5 -2
- package/dist/utils/has-esm-syntax.mjs +11 -0
- package/dist/utils/has-esm-syntax.mjs.map +6 -0
- package/dist/utils/index.d.mts +42 -0
- package/dist/utils/index.mjs +79 -0
- package/dist/utils/index.mjs.map +6 -0
- package/dist/utils/is-absolute-specifier.d.mts +19 -0
- package/dist/utils/is-absolute-specifier.mjs +25 -0
- package/dist/utils/is-absolute-specifier.mjs.map +6 -0
- package/dist/utils/is-bare-specifier.d.mts +19 -0
- package/dist/utils/is-bare-specifier.mjs +10 -0
- package/dist/utils/is-bare-specifier.mjs.map +6 -0
- package/dist/utils/is-exports-sugar.d.mts +25 -0
- package/dist/utils/is-exports-sugar.mjs +26 -0
- package/dist/utils/is-exports-sugar.mjs.map +6 -0
- package/dist/utils/is-relative-specifier.d.mts +20 -0
- package/dist/utils/is-relative-specifier.mjs +11 -0
- package/dist/utils/is-relative-specifier.mjs.map +6 -0
- package/dist/utils/lookup-package-scope.d.mts +26 -0
- package/dist/utils/lookup-package-scope.mjs +38 -0
- package/dist/utils/lookup-package-scope.mjs.map +6 -0
- package/dist/utils/parse-data-url.d.mts +25 -0
- package/dist/utils/parse-data-url.mjs +25 -0
- package/dist/utils/parse-data-url.mjs.map +6 -0
- package/dist/utils/parse-module-id.d.mts +22 -0
- package/dist/utils/parse-module-id.mjs +122 -0
- package/dist/utils/parse-module-id.mjs.map +6 -0
- package/dist/utils/parse-subpath.d.mts +35 -0
- package/dist/utils/parse-subpath.mjs +54 -0
- package/dist/utils/parse-subpath.mjs.map +6 -0
- package/dist/utils/pattern-character.d.mts +11 -0
- package/dist/utils/pattern-character.mjs +6 -0
- package/dist/utils/pattern-character.mjs.map +6 -0
- package/dist/utils/read-package-json.d.mts +26 -0
- package/dist/utils/read-package-json.mjs +43 -0
- package/dist/utils/read-package-json.mjs.map +6 -0
- package/dist/utils/resolve-alias.d.mts +20 -0
- package/dist/utils/resolve-alias.mjs +106 -0
- package/dist/utils/resolve-alias.mjs.map +6 -0
- package/dist/utils/resolve-aliases.d.mts +19 -0
- package/dist/utils/resolve-aliases.mjs +28 -0
- package/dist/utils/resolve-aliases.mjs.map +6 -0
- package/dist/utils/resolve-extensions.d.mts +14 -0
- package/dist/utils/resolve-extensions.mjs +22 -0
- package/dist/utils/resolve-extensions.mjs.map +6 -0
- package/dist/utils/resolve-module.d.mts +39 -0
- package/dist/utils/resolve-module.mjs +64 -0
- package/dist/utils/resolve-module.mjs.map +6 -0
- package/dist/utils/resolve-modules.d.mts +25 -0
- package/dist/{lib → utils}/resolve-modules.mjs +7 -10
- package/dist/utils/resolve-modules.mjs.map +6 -0
- package/dist/{lib → utils}/to-absolute-specifier.d.mts +6 -6
- package/dist/utils/to-absolute-specifier.mjs +8 -0
- package/dist/utils/to-absolute-specifier.mjs.map +6 -0
- package/dist/utils/to-bare-specifier.d.mts +42 -0
- package/dist/utils/to-bare-specifier.mjs +90 -0
- package/dist/utils/to-bare-specifier.mjs.map +6 -0
- package/dist/{lib → utils}/to-data-url.d.mts +6 -5
- package/dist/{lib → utils}/to-data-url.mjs +4 -0
- package/dist/utils/to-data-url.mjs.map +6 -0
- package/dist/utils/to-node-url.d.mts +19 -0
- package/dist/utils/to-node-url.mjs +10 -0
- package/dist/utils/to-node-url.mjs.map +6 -0
- package/dist/{lib → utils}/to-relative-specifier.d.mts +6 -6
- package/dist/{lib → utils}/to-relative-specifier.mjs +7 -3
- package/dist/utils/to-relative-specifier.mjs.map +6 -0
- package/dist/utils/to-url.d.mts +22 -0
- package/dist/utils/to-url.mjs +12 -0
- package/dist/utils/to-url.mjs.map +6 -0
- package/dist/utils/validate-assertions.d.mts +23 -0
- package/dist/utils/validate-assertions.mjs +52 -0
- package/dist/utils/validate-assertions.mjs.map +6 -0
- package/dist/utils/validate-exports.d.mts +24 -0
- package/dist/utils/validate-exports.mjs +72 -0
- package/dist/utils/validate-exports.mjs.map +6 -0
- package/package.json +106 -83
- package/src/enums/assert-type.ts +23 -0
- package/src/enums/format.ts +19 -0
- package/src/enums/index.ts +11 -0
- package/src/enums/kind-specifier-syntax.ts +16 -0
- package/src/enums/kind-specifier.ts +19 -0
- package/src/enums/kind-statement-syntax.ts +24 -0
- package/src/enums/kind-statement.ts +17 -0
- package/src/index.ts +9 -0
- package/src/interfaces/import-assertions.ts +24 -0
- package/src/interfaces/import-dynamic.ts +48 -0
- package/src/interfaces/import-static.ts +50 -0
- package/src/interfaces/index.ts +25 -0
- package/src/interfaces/options-fill-module.ts +26 -0
- package/src/interfaces/options-find-subpath.ts +56 -0
- package/src/interfaces/options-get-format.ts +92 -0
- package/src/interfaces/options-get-source.ts +70 -0
- package/src/interfaces/options-parse-module-id.ts +38 -0
- package/src/interfaces/options-parse-subpath.ts +36 -0
- package/src/interfaces/options-resolve-alias.ts +59 -0
- package/src/interfaces/options-resolve-module.ts +72 -0
- package/src/interfaces/options-resolve.ts +17 -0
- package/src/interfaces/package-scope.ts +30 -0
- package/src/interfaces/parsed-data-url.ts +63 -0
- package/src/interfaces/parsed-module-id.ts +90 -0
- package/src/interfaces/parsed-subpath.ts +47 -0
- package/src/interfaces/statement-export.ts +52 -0
- package/src/interfaces/statement-import.ts +45 -0
- package/src/interfaces/statement-require.ts +45 -0
- package/src/interfaces/statement.ts +64 -0
- package/src/internal/escape-reg-exp.ts +24 -0
- package/src/internal/format-type-map.ts +26 -0
- package/src/internal/get-specifier-kind.ts +38 -0
- package/src/internal/get-subpaths.ts +41 -0
- package/src/internal/is-array-index.ts +28 -0
- package/src/internal/is-directory.ts +25 -0
- package/src/internal/is-file.ts +25 -0
- package/src/internal/is-function.ts +16 -0
- package/src/internal/regex-encoded-sep.ts +15 -0
- package/src/internal/regex-internal-specifier.ts +17 -0
- package/src/internal/regex-package-name.ts +16 -0
- package/src/internal/regex-package-path.ts +18 -0
- package/src/internal/resolver.ts +783 -0
- package/src/internal/validate-boolean.ts +27 -0
- package/src/internal/validate-object.ts +30 -0
- package/src/internal/validate-set.ts +33 -0
- package/src/internal/validate-string.ts +27 -0
- package/src/internal/validate-url-string.ts +31 -0
- package/src/types/declaration.ts +22 -0
- package/src/types/fn-change-ext.ts +33 -0
- package/src/types/index.ts +14 -0
- package/src/types/mime-type.ts +19 -0
- package/src/types/module-id.ts +15 -0
- package/src/types/module-specifier-type.ts +13 -0
- package/src/types/protocol.ts +40 -0
- package/src/types/syntax-kind-export.ts +20 -0
- package/src/types/syntax-kind-import.ts +22 -0
- package/src/types/syntax-kind-require.ts +15 -0
- package/src/utils/compare-subpaths.ts +100 -0
- package/src/utils/conditions.ts +15 -0
- package/src/utils/detect-syntax.ts +40 -0
- package/src/utils/extension-format-map.ts +34 -0
- package/src/utils/extract-statements.ts +42 -0
- package/src/utils/fill-modules.ts +116 -0
- package/src/utils/find-dynamic-imports.ts +75 -0
- package/src/utils/find-exports.ts +164 -0
- package/src/utils/find-requires.ts +75 -0
- package/src/utils/find-static-imports.ts +89 -0
- package/src/utils/find-subpath.ts +241 -0
- package/src/utils/get-format.ts +222 -0
- package/src/utils/get-source.ts +129 -0
- package/src/utils/has-cjs-syntax.ts +44 -0
- package/src/utils/has-esm-syntax.ts +40 -0
- package/src/utils/index.ts +43 -0
- package/src/utils/is-absolute-specifier.ts +48 -0
- package/src/utils/is-bare-specifier.ts +30 -0
- package/src/utils/is-exports-sugar.ts +74 -0
- package/src/utils/is-relative-specifier.ts +34 -0
- package/src/utils/lookup-package-scope.ts +97 -0
- package/src/utils/parse-data-url.ts +71 -0
- package/src/utils/parse-module-id.ts +186 -0
- package/src/utils/parse-subpath.ts +173 -0
- package/src/utils/pattern-character.ts +13 -0
- package/src/utils/read-package-json.ts +101 -0
- package/src/utils/resolve-alias.ts +219 -0
- package/src/utils/resolve-aliases.ts +58 -0
- package/src/utils/resolve-extensions.ts +33 -0
- package/src/utils/resolve-module.ts +153 -0
- package/src/utils/resolve-modules.ts +62 -0
- package/src/utils/to-absolute-specifier.ts +30 -0
- package/src/utils/to-bare-specifier.ts +201 -0
- package/src/utils/to-data-url.ts +42 -0
- package/src/utils/to-node-url.ts +27 -0
- package/src/utils/to-relative-specifier.ts +47 -0
- package/src/utils/to-url.ts +31 -0
- package/src/utils/validate-assertions.ts +119 -0
- package/src/utils/validate-exports.ts +124 -0
- package/changelog.config.cts +0 -204
- package/dist/constants.d.mts +0 -19
- package/dist/constants.mjs +0 -24
- package/dist/interfaces/import-dynamic.mjs +0 -0
- package/dist/interfaces/import-static.mjs +0 -0
- package/dist/interfaces/options-resolve-alias.mjs +0 -0
- package/dist/interfaces/options-resolve.mjs +0 -0
- package/dist/interfaces/statement-export.mjs +0 -0
- package/dist/interfaces/statement-import.mjs +0 -0
- package/dist/interfaces/statement-require.mjs +0 -0
- package/dist/interfaces/statement.mjs +0 -0
- package/dist/internal/compiler-options-json.d.mts +0 -111
- package/dist/internal/compiler-options-json.mjs +0 -0
- package/dist/internal/constants.d.mts +0 -70
- package/dist/internal/constants.mjs +0 -18
- package/dist/internal/get-compiler-options.d.mts +0 -21
- package/dist/internal/get-compiler-options.mjs +0 -14
- package/dist/internal/index.d.mts +0 -7
- package/dist/internal/index.mjs +0 -5
- package/dist/lib/extract-statements.d.mts +0 -21
- package/dist/lib/find-dynamic-imports.d.mts +0 -15
- package/dist/lib/find-dynamic-imports.mjs +0 -20
- package/dist/lib/find-exports.d.mts +0 -15
- package/dist/lib/find-exports.mjs +0 -53
- package/dist/lib/find-requires.d.mts +0 -17
- package/dist/lib/find-requires.mjs +0 -19
- package/dist/lib/find-static-imports.d.mts +0 -15
- package/dist/lib/find-static-imports.mjs +0 -20
- package/dist/lib/has-cjs-syntax.mjs +0 -6
- package/dist/lib/has-esm-syntax.mjs +0 -6
- package/dist/lib/index.d.mts +0 -20
- package/dist/lib/index.mjs +0 -34
- package/dist/lib/resolve-alias.d.mts +0 -20
- package/dist/lib/resolve-alias.mjs +0 -41
- package/dist/lib/resolve-aliases.d.mts +0 -17
- package/dist/lib/resolve-aliases.mjs +0 -34
- package/dist/lib/resolve-module.d.mts +0 -31
- package/dist/lib/resolve-module.mjs +0 -74
- package/dist/lib/resolve-modules.d.mts +0 -19
- package/dist/lib/to-absolute-specifier.mjs +0 -20
- package/dist/lib/to-bare-specifier.d.mts +0 -28
- package/dist/lib/to-bare-specifier.mjs +0 -78
- package/dist/types/declaration.mjs +0 -0
- package/dist/types/ext.d.mts +0 -9
- package/dist/types/ext.mjs +0 -0
- package/dist/types/mime-type.mjs +0 -0
- package/dist/types/specifier-type.d.mts +0 -11
- package/dist/types/specifier-type.mjs +0 -0
- package/dist/types/statement-type.d.mts +0 -9
- package/dist/types/statement-type.mjs +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file resolveModule
|
|
3
|
+
* @module mlly/utils/resolveModule
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ResolveModuleOptions } from '#src/interfaces'
|
|
7
|
+
import isFunction from '#src/internal/is-function'
|
|
8
|
+
import Resolver from '#src/internal/resolver'
|
|
9
|
+
import { ErrorCode, type NodeError } from '@flex-development/errnode'
|
|
10
|
+
import { isBuiltin } from '@flex-development/is-builtin'
|
|
11
|
+
import pathe from '@flex-development/pathe'
|
|
12
|
+
import type { Nullable } from '@flex-development/tutils'
|
|
13
|
+
import { URL, fileURLToPath } from 'node:url'
|
|
14
|
+
import CONDITIONS from './conditions'
|
|
15
|
+
import RESOLVE_EXTENSIONS from './resolve-extensions'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Resolves `specifier` according to the [ESM Resolver algorithm][1], mostly 😉.
|
|
19
|
+
*
|
|
20
|
+
* Adds support for:
|
|
21
|
+
*
|
|
22
|
+
* - Extensionless file and directory index resolution
|
|
23
|
+
* - Replacing file extensions
|
|
24
|
+
*
|
|
25
|
+
* Other differences between Node.js:
|
|
26
|
+
*
|
|
27
|
+
* - [Subpath import][2] targets (that are strings) must be relative to the
|
|
28
|
+
* current working directory (e.g. `'./src/index.ts'`, `'./src/*.ts'`) or
|
|
29
|
+
* start with a [NPM valid package name][3]. See [`nodejs/node#40579`][4] for
|
|
30
|
+
* details.
|
|
31
|
+
*
|
|
32
|
+
* [1]: https://nodejs.org/api/esm.html#esm_resolver_algorithm
|
|
33
|
+
* [2]: https://nodejs.org/api/packages.html#subpath-imports
|
|
34
|
+
* [3]: https://regex101.com/r/BHcJfc
|
|
35
|
+
* [4]: https://github.com/nodejs/node/issues/40579
|
|
36
|
+
*
|
|
37
|
+
* @see {@linkcode NodeError}
|
|
38
|
+
* @see {@linkcode ResolveModuleOptions}
|
|
39
|
+
* @see {@linkcode URL}
|
|
40
|
+
*
|
|
41
|
+
* @async
|
|
42
|
+
*
|
|
43
|
+
* @param {string} specifier - Module specifier to resolve
|
|
44
|
+
* @param {ResolveModuleOptions} [options={}] - Module resolution options
|
|
45
|
+
* @return {Promise<URL>} Resolved module URL
|
|
46
|
+
* @throws {NodeError}
|
|
47
|
+
*/
|
|
48
|
+
const resolveModule = async (
|
|
49
|
+
specifier: string,
|
|
50
|
+
options: ResolveModuleOptions = {}
|
|
51
|
+
): Promise<URL> => {
|
|
52
|
+
const {
|
|
53
|
+
condition = 'default',
|
|
54
|
+
conditions = CONDITIONS,
|
|
55
|
+
extensions = RESOLVE_EXTENSIONS,
|
|
56
|
+
parent = import.meta.url,
|
|
57
|
+
preserveSymlinks = false
|
|
58
|
+
} = options
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Module resolver.
|
|
62
|
+
*
|
|
63
|
+
* @const {Resolver} resolver
|
|
64
|
+
*/
|
|
65
|
+
const resolver: Resolver = new Resolver()
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Module ids to try resolving.
|
|
69
|
+
*
|
|
70
|
+
* @const {string[]} tries
|
|
71
|
+
*/
|
|
72
|
+
const tries: string[] =
|
|
73
|
+
isBuiltin(specifier) ||
|
|
74
|
+
(/^\S+:/.test(specifier) && !specifier.startsWith('file:'))
|
|
75
|
+
? []
|
|
76
|
+
: [...extensions]
|
|
77
|
+
.flatMap(ext => [
|
|
78
|
+
specifier + (ext = pathe.formatExt(ext)),
|
|
79
|
+
specifier.startsWith('#') ? specifier + '/index' : '',
|
|
80
|
+
specifier + '/index' + ext
|
|
81
|
+
])
|
|
82
|
+
.filter(id => id.length > 0)
|
|
83
|
+
|
|
84
|
+
// ensure attempt to resolve original specifier is first
|
|
85
|
+
tries.unshift(specifier)
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Error codes to ignore when attempting to resolve {@linkcode specifier}.
|
|
89
|
+
*
|
|
90
|
+
* **Note**: If an error is thrown, it'll be reported **_after_** all module
|
|
91
|
+
* ids in {@linkcode tries} have been evaluated.
|
|
92
|
+
*
|
|
93
|
+
* @const {Set<ErrorCode>} ignore
|
|
94
|
+
*/
|
|
95
|
+
const ignore: Set<ErrorCode> = new Set<ErrorCode>([
|
|
96
|
+
ErrorCode.ERR_MODULE_NOT_FOUND,
|
|
97
|
+
ErrorCode.ERR_PACKAGE_PATH_NOT_EXPORTED,
|
|
98
|
+
ErrorCode.ERR_UNSUPPORTED_DIR_IMPORT
|
|
99
|
+
])
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Module resolution error.
|
|
103
|
+
*
|
|
104
|
+
* @var {NodeError} error
|
|
105
|
+
*/
|
|
106
|
+
let error: NodeError
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolved module URL.
|
|
110
|
+
*
|
|
111
|
+
* @var {Nullable<URL>} url
|
|
112
|
+
*/
|
|
113
|
+
let url: Nullable<URL> = null
|
|
114
|
+
|
|
115
|
+
// try module resolution
|
|
116
|
+
for (const id of tries) {
|
|
117
|
+
try {
|
|
118
|
+
url = resolver.resolveModule(
|
|
119
|
+
id,
|
|
120
|
+
parent,
|
|
121
|
+
condition,
|
|
122
|
+
new Set(conditions),
|
|
123
|
+
preserveSymlinks
|
|
124
|
+
)
|
|
125
|
+
} catch (e: unknown) {
|
|
126
|
+
url = null
|
|
127
|
+
if (id === specifier) error = e as NodeError
|
|
128
|
+
if (!ignore.has((e as NodeError).code)) throw e
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// stop resolution attempts if module was resolved
|
|
132
|
+
if (url) break
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// throw if module was not resolved
|
|
136
|
+
if (!url) throw error!
|
|
137
|
+
|
|
138
|
+
// replace file extension
|
|
139
|
+
if (url.protocol === 'file:') {
|
|
140
|
+
let { ext } = options
|
|
141
|
+
|
|
142
|
+
// get replacement extension
|
|
143
|
+
ext = isFunction(ext) ? await ext(specifier, url) : ext
|
|
144
|
+
|
|
145
|
+
// replace file extension in url href and pathname
|
|
146
|
+
url.href = pathe.changeExt(url.href, ext).replace(/\/index$/, '')
|
|
147
|
+
url.pathname = fileURLToPath(url.href)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return url
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export default resolveModule
|
|
@@ -0,0 +1,62 @@
|
|
|
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 '#src/internal/escape-reg-exp'
|
|
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
|
+
// do nothing if statement does not have specifier
|
|
37
|
+
if (!statement.specifier) continue
|
|
38
|
+
|
|
39
|
+
// ignore statements with dynamic specifiers
|
|
40
|
+
if (statement.specifier_syntax === SpecifierSyntaxKind.DYNAMIC) continue
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Resolved module URL.
|
|
44
|
+
*
|
|
45
|
+
* @const {URL} url
|
|
46
|
+
*/
|
|
47
|
+
const url: URL = await resolveModule(statement.specifier, options)
|
|
48
|
+
|
|
49
|
+
// replace original specifier
|
|
50
|
+
code = code.replace(
|
|
51
|
+
statement.code,
|
|
52
|
+
statement.code.replace(
|
|
53
|
+
new RegExp(`(?<=["'])${regexp(statement.specifier)}(?=["'])`),
|
|
54
|
+
url.href
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return code
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default resolveModules
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toBareSpecifier
|
|
3
|
+
* @module mlly/utils/toBareSpecifier
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { PackageScope, ParsedModuleId } from '#src/interfaces'
|
|
7
|
+
import regexp from '#src/internal/escape-reg-exp'
|
|
8
|
+
import validateURLString from '#src/internal/validate-url-string'
|
|
9
|
+
import type { ModuleId } from '#src/types'
|
|
10
|
+
import {
|
|
11
|
+
ERR_OPERATION_FAILED,
|
|
12
|
+
ERR_PACKAGE_PATH_NOT_EXPORTED,
|
|
13
|
+
ErrorCode,
|
|
14
|
+
type NodeError
|
|
15
|
+
} from '@flex-development/errnode'
|
|
16
|
+
import { isBuiltin } from '@flex-development/is-builtin'
|
|
17
|
+
import pathe from '@flex-development/pathe'
|
|
18
|
+
import { isNIL, type Nullable } from '@flex-development/tutils'
|
|
19
|
+
import { URL, fileURLToPath, pathToFileURL } from 'node:url'
|
|
20
|
+
import CONDITIONS from './conditions'
|
|
21
|
+
import findSubpath from './find-subpath'
|
|
22
|
+
import isAbsoluteSpecifier from './is-absolute-specifier'
|
|
23
|
+
import isRelativeSpecifier from './is-relative-specifier'
|
|
24
|
+
import lookupPackageScope from './lookup-package-scope'
|
|
25
|
+
import parseModuleId from './parse-module-id'
|
|
26
|
+
import parseSubpath from './parse-subpath'
|
|
27
|
+
import PATTERN_CHARACTER from './pattern-character'
|
|
28
|
+
import toAbsoluteSpecifier from './to-absolute-specifier'
|
|
29
|
+
import toNodeURL from './to-node-url'
|
|
30
|
+
import toURL from './to-url'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Converts the given module `specifier` into a bare specifier.
|
|
34
|
+
*
|
|
35
|
+
* The new specifier is **not** guaranteed to resolve to an existing module, nor
|
|
36
|
+
* is it guaranteed to have a file extension, but it *is* guaranteed to be a
|
|
37
|
+
* package path containing a valid [subpath export][1] if the specifier's parent
|
|
38
|
+
* package uses package [`exports`][2]. If the parent package does not use
|
|
39
|
+
* `exports`, the new specifier is only guaranteed to begin with a valid NPM
|
|
40
|
+
* package name or Node.js [builtin module][3] name.
|
|
41
|
+
*
|
|
42
|
+
* The given module `specifier` should be absolute, syntactically bare (i.e. not
|
|
43
|
+
* begin with `'/'` or `'.'`), or relative to the current working directory
|
|
44
|
+
* (e.g. `'./dist/index.mjs'`).
|
|
45
|
+
*
|
|
46
|
+
* ::: warning
|
|
47
|
+
* Internal specifier (i.e. [subpath import][4]; `'#src'`, `'#src/utils'`)
|
|
48
|
+
* conversion is not supported. Converting *_to_* an internal specifier will be
|
|
49
|
+
* supported in the future.
|
|
50
|
+
* :::
|
|
51
|
+
*
|
|
52
|
+
* [1]: https://nodejs.org/api/packages.html#subpath-exports
|
|
53
|
+
* [2]: https://nodejs.org/api/packages.html#exports
|
|
54
|
+
* [3]: https://nodejs.org/api/module.html#modulebuiltinmodules
|
|
55
|
+
* [4]: https://nodejs.org/api/packages.html#subpath-imports
|
|
56
|
+
*
|
|
57
|
+
* @see {@linkcode CONDITIONS}
|
|
58
|
+
* @see {@linkcode ModuleId}
|
|
59
|
+
* @see https://nodejs.org/api/esm.html#terminology
|
|
60
|
+
*
|
|
61
|
+
* @param {ModuleId} specifier - Module specifier to convert
|
|
62
|
+
* @param {ModuleId} parent - URL of module to resolve from
|
|
63
|
+
* @param {Set<string>?} [conditions=CONDITIONS] - Export conditions
|
|
64
|
+
* @return {string} `specifier` as bare specifier
|
|
65
|
+
* @throws {NodeError}
|
|
66
|
+
*/
|
|
67
|
+
const toBareSpecifier = (
|
|
68
|
+
specifier: ModuleId,
|
|
69
|
+
parent: ModuleId,
|
|
70
|
+
conditions: Set<string> = CONDITIONS
|
|
71
|
+
): string => {
|
|
72
|
+
validateURLString(specifier, 'specifier')
|
|
73
|
+
validateURLString(parent, 'parent')
|
|
74
|
+
|
|
75
|
+
// ensure specifier is a string
|
|
76
|
+
if (specifier instanceof URL) specifier = specifier.href
|
|
77
|
+
|
|
78
|
+
// exit early if specifier is builtin module
|
|
79
|
+
if (isBuiltin(specifier)) return toNodeURL(specifier)
|
|
80
|
+
|
|
81
|
+
// ensure specifier is a path
|
|
82
|
+
if (specifier.startsWith('file:')) specifier = fileURLToPath(specifier)
|
|
83
|
+
|
|
84
|
+
// convert relative specifiers to absolute paths
|
|
85
|
+
if (isRelativeSpecifier(specifier)) {
|
|
86
|
+
specifier = fileURLToPath(toAbsoluteSpecifier(specifier))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Location to begin package scope search for {@linkcode specifier}.
|
|
91
|
+
*
|
|
92
|
+
* @const {URL} url
|
|
93
|
+
*/
|
|
94
|
+
const url: URL = toURL(
|
|
95
|
+
isAbsoluteSpecifier(specifier) || specifier.startsWith('node_modules')
|
|
96
|
+
? specifier
|
|
97
|
+
: `node_modules/${specifier}`
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Package scope result for {@linkcode specifier}.
|
|
102
|
+
*
|
|
103
|
+
* @const {Nullable<PackageScope>} scope
|
|
104
|
+
*/
|
|
105
|
+
const scope: Nullable<PackageScope> = lookupPackageScope(
|
|
106
|
+
url,
|
|
107
|
+
pathToFileURL('.')
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
// throw if package scope was not found
|
|
111
|
+
if (!scope) {
|
|
112
|
+
throw new ERR_OPERATION_FAILED(`Package scope for '${specifier}' not found`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// get directory containing package.json file and package.json object
|
|
116
|
+
const { dir: pkgdir, pkgjson } = scope
|
|
117
|
+
|
|
118
|
+
// get package exports and name
|
|
119
|
+
const { exports, main, name = '', types } = pkgjson
|
|
120
|
+
|
|
121
|
+
// convert specifier to bare specifier
|
|
122
|
+
specifier = url.pathname.includes(name)
|
|
123
|
+
? name + url.pathname.replace(new RegExp(`.*?${regexp(name)}`), '')
|
|
124
|
+
: name + specifier.replace(fileURLToPath(pkgdir.replace(/\/$/, '')), '')
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Parsed module specifier.
|
|
128
|
+
*
|
|
129
|
+
* Ensures {@linkcode specifier} has become a bare specifier.
|
|
130
|
+
*
|
|
131
|
+
* @const {ParsedModuleId} id
|
|
132
|
+
*/
|
|
133
|
+
const id: ParsedModuleId = parseModuleId(specifier, {
|
|
134
|
+
internal: false,
|
|
135
|
+
parent,
|
|
136
|
+
pkgname: true
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// exit early if subpath does not need to be validated
|
|
140
|
+
if (isNIL(exports)) {
|
|
141
|
+
return [main, types].some(ep => ep === id.path || ep === id.path.slice(2))
|
|
142
|
+
? id.pkg
|
|
143
|
+
: specifier
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// check if specifier contains valid subpath export
|
|
147
|
+
try {
|
|
148
|
+
parseSubpath(specifier, exports, { dir: pkgdir, parent })
|
|
149
|
+
} catch (e: unknown) {
|
|
150
|
+
// try finding defined subpath if specifier is invalid package path
|
|
151
|
+
if ((e as NodeError).code === ErrorCode.ERR_PACKAGE_PATH_NOT_EXPORTED) {
|
|
152
|
+
/**
|
|
153
|
+
* Package target to find defined subpath for.
|
|
154
|
+
*
|
|
155
|
+
* @const {string} target
|
|
156
|
+
*/
|
|
157
|
+
const target: string = specifier.replace(name, '.')
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Subpath in {@linkcode exports} thats maps to {@linkcode target}, if any
|
|
161
|
+
* at all.
|
|
162
|
+
*
|
|
163
|
+
* @var {Nullable<string>} subpath
|
|
164
|
+
*/
|
|
165
|
+
let subpath: Nullable<string> = findSubpath(target, exports, {
|
|
166
|
+
conditions,
|
|
167
|
+
dir: pkgdir,
|
|
168
|
+
parent
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
// throw if target was not matched to a subpath
|
|
172
|
+
if (subpath === null) {
|
|
173
|
+
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
|
|
174
|
+
fileURLToPath(pkgdir),
|
|
175
|
+
id.path,
|
|
176
|
+
fileURLToPath(parent)
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// replace pattern character in subpath
|
|
181
|
+
if (subpath.includes(PATTERN_CHARACTER)) {
|
|
182
|
+
subpath = subpath.slice(0, subpath.indexOf(PATTERN_CHARACTER)).slice(1)
|
|
183
|
+
subpath = '.' + target.slice(target.indexOf(subpath))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// subpath should not include extension if extension is already included
|
|
187
|
+
// via package target
|
|
188
|
+
if (pathe.extname(target) === pathe.extname(subpath)) {
|
|
189
|
+
subpath = pathe.changeExt(subpath, '')
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return name + subpath.slice(1)
|
|
193
|
+
} /* c8 ignore next 3 */
|
|
194
|
+
// throw original error if package path error is not encountered
|
|
195
|
+
throw e
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return specifier
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export default toBareSpecifier
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toDataURL
|
|
3
|
+
* @module mlly/utils/toDataURL
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import validateString from '#src/internal/validate-string'
|
|
7
|
+
import type { MimeType } from '#src/types'
|
|
8
|
+
import type { NodeError } from '@flex-development/errnode'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Converts `code` into a [`data:` URL][1] using `base64` encoding.
|
|
12
|
+
*
|
|
13
|
+
* ::: tip
|
|
14
|
+
* `data:` URLs only resolve [bare specifiers][2] for builtin modules and
|
|
15
|
+
* [absolute specifiers][2].
|
|
16
|
+
*
|
|
17
|
+
* Call [`await resolveModules(code)`][3] to ensure all specifiers are absolute
|
|
18
|
+
* or bare.
|
|
19
|
+
* :::
|
|
20
|
+
*
|
|
21
|
+
* [1]: https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
|
|
22
|
+
* [2]: https://nodejs.org/api/esm.html#terminology
|
|
23
|
+
* [3]: {@link ./resolve-modules.ts}
|
|
24
|
+
*
|
|
25
|
+
* @see {@linkcode MimeType}
|
|
26
|
+
* @see https://nodejs.org/api/esm.html#esm_data_imports
|
|
27
|
+
*
|
|
28
|
+
* @param {string} code - Code to convert
|
|
29
|
+
* @param {MimeType} [mime='text/javascript'] - MIME type
|
|
30
|
+
* @return {string} `code` as `data:` URL
|
|
31
|
+
* @throws {NodeError<TypeError>} If `code` or `mime` is not a string
|
|
32
|
+
*/
|
|
33
|
+
const toDataURL = (
|
|
34
|
+
code: string,
|
|
35
|
+
mime: MimeType = 'text/javascript'
|
|
36
|
+
): string => {
|
|
37
|
+
validateString(code, 'code')
|
|
38
|
+
validateString(mime, 'mime')
|
|
39
|
+
return `data:${mime};base64,${Buffer.from(code).toString('base64')}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default toDataURL
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toNodeURL
|
|
3
|
+
* @module mlly/utils/toNodeURL
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import validateString from '#src/internal/validate-string'
|
|
7
|
+
import type { NodeError } from '@flex-development/errnode'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Converts the given module `specifier` to a `node:` URL.
|
|
11
|
+
*
|
|
12
|
+
* ::: warning
|
|
13
|
+
* Does not guarantee the new specifier is an existing Node.js builtin module.
|
|
14
|
+
* :::
|
|
15
|
+
*
|
|
16
|
+
* @see https://nodejs.org/api/esm.html#node-imports
|
|
17
|
+
*
|
|
18
|
+
* @param {string} specifier - Module specifier to convert
|
|
19
|
+
* @return {string} `specifier` as `node:` URL
|
|
20
|
+
* @throws {NodeError<TypeError>} If `specifier` is not a string
|
|
21
|
+
*/
|
|
22
|
+
const toNodeURL = (specifier: string): string => {
|
|
23
|
+
validateString(specifier, 'specifier')
|
|
24
|
+
return specifier.startsWith('node:') ? specifier : `node:${specifier}`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default toNodeURL
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toRelativeSpecifier
|
|
3
|
+
* @module mlly/utils/toRelativeSpecifier
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ModuleId } from '#src/types'
|
|
7
|
+
import pathe from '@flex-development/pathe'
|
|
8
|
+
import { URL, fileURLToPath } from 'node:url'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Converts `specifier` into a relative specifier.
|
|
12
|
+
*
|
|
13
|
+
* ::: info
|
|
14
|
+
* The relative 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} parent - Parent module URL or path to resolve from
|
|
23
|
+
* @return {string} `specifier` as relative specifier
|
|
24
|
+
*/
|
|
25
|
+
const toRelativeSpecifier = (specifier: ModuleId, parent: ModuleId): string => {
|
|
26
|
+
// convert file url objects to file url strings
|
|
27
|
+
if (parent instanceof URL) parent = parent.href
|
|
28
|
+
if (specifier instanceof URL) specifier = specifier.href
|
|
29
|
+
|
|
30
|
+
// convert file url strings to paths
|
|
31
|
+
if (parent.startsWith('file:')) parent = fileURLToPath(parent)
|
|
32
|
+
if (specifier.startsWith('file:')) specifier = fileURLToPath(specifier)
|
|
33
|
+
|
|
34
|
+
// convert specifier to relative specifier
|
|
35
|
+
specifier = pathe
|
|
36
|
+
.relative(pathe.resolve(parent), pathe.resolve(specifier))
|
|
37
|
+
.replace(/^\.\.\/?/, '')
|
|
38
|
+
.replace(/^(\w)/, './$1')
|
|
39
|
+
|
|
40
|
+
// set specifier to dot character if empty string
|
|
41
|
+
// this occurs when specifier is a directory, but is not fully specified
|
|
42
|
+
if (!specifier) specifier = '.'
|
|
43
|
+
|
|
44
|
+
return specifier
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default toRelativeSpecifier
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toURL
|
|
3
|
+
* @module mlly/utils/toURL
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import validateURLString from '#src/internal/validate-url-string'
|
|
7
|
+
import type { ModuleId } from '#src/types'
|
|
8
|
+
import type { NodeError } from '@flex-development/errnode'
|
|
9
|
+
import { URL, pathToFileURL } from 'node:url'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Converts the given module `id` to an instance of [`URL`][1].
|
|
13
|
+
*
|
|
14
|
+
* [1]: https://nodejs.org/api/url.html#class-url
|
|
15
|
+
*
|
|
16
|
+
* @see {@linkcode ModuleId}
|
|
17
|
+
*
|
|
18
|
+
* @param {ModuleId} id - Module id to evaluate
|
|
19
|
+
* @param {ModuleId?} [base=pathToFileURL('./')] - Base URL to resolve against
|
|
20
|
+
* if `id` is not absolute
|
|
21
|
+
* @return {URL} `id` as instance of `URL`
|
|
22
|
+
* @throws {NodeError<TypeError>} If either `id` or `base` is not a string or an
|
|
23
|
+
* instance of `URL`
|
|
24
|
+
*/
|
|
25
|
+
const toURL = (id: ModuleId, base: ModuleId = pathToFileURL('./')): URL => {
|
|
26
|
+
validateURLString(id, 'id')
|
|
27
|
+
validateURLString(base, 'base')
|
|
28
|
+
return id instanceof URL ? id : new URL(id, base)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default toURL
|