@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.
Files changed (175) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.mjs.map +4 -5
  3. package/dist/internal/dequote.mjs +1 -0
  4. package/dist/internal/dequote.mjs.map +8 -0
  5. package/dist/internal/format-type-map.mjs +1 -0
  6. package/dist/internal/format-type-map.mjs.map +8 -0
  7. package/dist/internal/get-specifier-kind.mjs +1 -0
  8. package/dist/internal/get-specifier-kind.mjs.map +8 -0
  9. package/dist/internal/get-subpaths.mjs +1 -0
  10. package/dist/internal/get-subpaths.mjs.map +8 -0
  11. package/dist/internal/regex-encoded-sep.mjs +1 -0
  12. package/dist/internal/regex-encoded-sep.mjs.map +8 -0
  13. package/dist/internal/regex-internal-specifier.mjs +1 -0
  14. package/dist/internal/regex-internal-specifier.mjs.map +8 -0
  15. package/dist/internal/regex-invalid-segment.mjs +1 -0
  16. package/dist/internal/regex-invalid-segment.mjs.map +8 -0
  17. package/dist/internal/regex-package-name.mjs +1 -0
  18. package/dist/internal/regex-package-name.mjs.map +8 -0
  19. package/dist/internal/regex-package-path.mjs +1 -0
  20. package/dist/internal/regex-package-path.mjs.map +8 -0
  21. package/dist/internal/resolver.mjs +1 -0
  22. package/dist/internal/resolver.mjs.map +8 -0
  23. package/dist/internal/validate-array-set.mjs +1 -0
  24. package/dist/internal/validate-array-set.mjs.map +8 -0
  25. package/dist/internal/validate-boolean.mjs +1 -0
  26. package/dist/internal/validate-boolean.mjs.map +8 -0
  27. package/dist/internal/validate-map.mjs +1 -0
  28. package/dist/internal/validate-map.mjs.map +8 -0
  29. package/dist/internal/validate-object.mjs +1 -0
  30. package/dist/internal/validate-object.mjs.map +8 -0
  31. package/dist/internal/validate-set.mjs +1 -0
  32. package/dist/internal/validate-set.mjs.map +8 -0
  33. package/dist/internal/validate-string.mjs +1 -0
  34. package/dist/internal/validate-string.mjs.map +8 -0
  35. package/dist/internal/validate-url-string.mjs +1 -0
  36. package/dist/internal/validate-url-string.mjs.map +8 -0
  37. package/dist/utils/compare-subpaths.mjs.map +4 -5
  38. package/dist/utils/conditions.mjs.map +4 -5
  39. package/dist/utils/detect-syntax.mjs.map +4 -5
  40. package/dist/utils/extension-format-map.mjs.map +4 -5
  41. package/dist/utils/extract-statements.mjs.map +4 -5
  42. package/dist/utils/fill-modules.mjs.map +5 -8
  43. package/dist/utils/find-dynamic-imports.mjs.map +5 -8
  44. package/dist/utils/find-exports.mjs.map +5 -8
  45. package/dist/utils/find-requires.mjs.map +5 -8
  46. package/dist/utils/find-static-imports.mjs.map +5 -8
  47. package/dist/utils/find-subpath.mjs.map +5 -9
  48. package/dist/utils/get-format.mjs.map +5 -8
  49. package/dist/utils/get-source.mjs.map +4 -5
  50. package/dist/utils/has-cjs-syntax.mjs.map +4 -5
  51. package/dist/utils/has-esm-syntax.mjs.map +4 -5
  52. package/dist/utils/index.mjs.map +5 -8
  53. package/dist/utils/is-absolute-specifier.mjs.map +4 -5
  54. package/dist/utils/is-bare-specifier.mjs.map +4 -5
  55. package/dist/utils/is-directory.mjs.map +4 -5
  56. package/dist/utils/is-exports-sugar.mjs.map +4 -5
  57. package/dist/utils/is-file.mjs.map +4 -5
  58. package/dist/utils/is-relative-specifier.mjs.map +4 -5
  59. package/dist/utils/lookup-package-scope.mjs.map +4 -5
  60. package/dist/utils/parse-data-url.mjs.map +4 -5
  61. package/dist/utils/parse-module-id.mjs.map +5 -9
  62. package/dist/utils/parse-subpath.mjs.map +5 -8
  63. package/dist/utils/pattern-character.mjs.map +4 -5
  64. package/dist/utils/read-package-json.mjs.map +4 -5
  65. package/dist/utils/resolve-alias.mjs.map +5 -9
  66. package/dist/utils/resolve-aliases.mjs.map +4 -5
  67. package/dist/utils/resolve-extensions.mjs.map +4 -5
  68. package/dist/utils/resolve-module.mjs.map +4 -5
  69. package/dist/utils/resolve-modules.mjs.map +4 -5
  70. package/dist/utils/to-absolute-specifier.mjs.map +4 -5
  71. package/dist/utils/to-bare-specifier.mjs.map +4 -5
  72. package/dist/utils/to-data-url.mjs.map +4 -5
  73. package/dist/utils/to-node-url.mjs.map +4 -5
  74. package/dist/utils/to-relative-specifier.mjs.map +4 -5
  75. package/dist/utils/to-url.mjs.map +4 -5
  76. package/dist/utils/validate-assertions.mjs.map +5 -8
  77. package/dist/utils/validate-exports.mjs.map +4 -5
  78. package/package.json +8 -9
  79. package/src/enums/assert-type.ts +0 -23
  80. package/src/enums/format.ts +0 -19
  81. package/src/enums/index.ts +0 -11
  82. package/src/enums/kind-specifier-syntax.ts +0 -16
  83. package/src/enums/kind-specifier.ts +0 -19
  84. package/src/enums/kind-statement-syntax.ts +0 -24
  85. package/src/enums/kind-statement.ts +0 -17
  86. package/src/index.ts +0 -9
  87. package/src/interfaces/import-assertions.ts +0 -24
  88. package/src/interfaces/import-dynamic.ts +0 -46
  89. package/src/interfaces/import-static.ts +0 -46
  90. package/src/interfaces/index.ts +0 -25
  91. package/src/interfaces/options-fill-module.ts +0 -26
  92. package/src/interfaces/options-find-subpath.ts +0 -57
  93. package/src/interfaces/options-get-format.ts +0 -80
  94. package/src/interfaces/options-get-source.ts +0 -59
  95. package/src/interfaces/options-parse-module-id.ts +0 -39
  96. package/src/interfaces/options-parse-subpath.ts +0 -57
  97. package/src/interfaces/options-resolve-alias.ts +0 -59
  98. package/src/interfaces/options-resolve-module.ts +0 -72
  99. package/src/interfaces/options-resolve.ts +0 -17
  100. package/src/interfaces/package-scope.ts +0 -30
  101. package/src/interfaces/parsed-data-url.ts +0 -63
  102. package/src/interfaces/parsed-module-id.ts +0 -90
  103. package/src/interfaces/parsed-subpath.ts +0 -56
  104. package/src/interfaces/statement-export.ts +0 -52
  105. package/src/interfaces/statement-import.ts +0 -45
  106. package/src/interfaces/statement-require.ts +0 -45
  107. package/src/interfaces/statement.ts +0 -64
  108. package/src/internal/dequote.ts +0 -18
  109. package/src/internal/format-type-map.ts +0 -28
  110. package/src/internal/get-specifier-kind.ts +0 -41
  111. package/src/internal/get-subpaths.ts +0 -43
  112. package/src/internal/regex-encoded-sep.ts +0 -17
  113. package/src/internal/regex-internal-specifier.ts +0 -19
  114. package/src/internal/regex-invalid-segment.ts +0 -25
  115. package/src/internal/regex-package-name.ts +0 -18
  116. package/src/internal/regex-package-path.ts +0 -20
  117. package/src/internal/resolver.ts +0 -790
  118. package/src/internal/validate-array-set.ts +0 -35
  119. package/src/internal/validate-boolean.ts +0 -30
  120. package/src/internal/validate-map.ts +0 -36
  121. package/src/internal/validate-object.ts +0 -30
  122. package/src/internal/validate-set.ts +0 -32
  123. package/src/internal/validate-string.ts +0 -31
  124. package/src/internal/validate-url-string.ts +0 -34
  125. package/src/types/declaration.ts +0 -22
  126. package/src/types/fn-change-ext.ts +0 -33
  127. package/src/types/index.ts +0 -14
  128. package/src/types/mime-type.ts +0 -19
  129. package/src/types/module-id.ts +0 -15
  130. package/src/types/module-specifier-type.ts +0 -13
  131. package/src/types/protocol.ts +0 -40
  132. package/src/types/syntax-kind-export.ts +0 -20
  133. package/src/types/syntax-kind-import.ts +0 -22
  134. package/src/types/syntax-kind-require.ts +0 -15
  135. package/src/utils/compare-subpaths.ts +0 -100
  136. package/src/utils/conditions.ts +0 -15
  137. package/src/utils/detect-syntax.ts +0 -40
  138. package/src/utils/extension-format-map.ts +0 -34
  139. package/src/utils/extract-statements.ts +0 -46
  140. package/src/utils/fill-modules.ts +0 -133
  141. package/src/utils/find-dynamic-imports.ts +0 -75
  142. package/src/utils/find-exports.ts +0 -156
  143. package/src/utils/find-requires.ts +0 -75
  144. package/src/utils/find-static-imports.ts +0 -86
  145. package/src/utils/find-subpath.ts +0 -251
  146. package/src/utils/get-format.ts +0 -249
  147. package/src/utils/get-source.ts +0 -144
  148. package/src/utils/has-cjs-syntax.ts +0 -44
  149. package/src/utils/has-esm-syntax.ts +0 -40
  150. package/src/utils/index.ts +0 -45
  151. package/src/utils/is-absolute-specifier.ts +0 -53
  152. package/src/utils/is-bare-specifier.ts +0 -36
  153. package/src/utils/is-directory.ts +0 -25
  154. package/src/utils/is-exports-sugar.ts +0 -81
  155. package/src/utils/is-file.ts +0 -25
  156. package/src/utils/is-relative-specifier.ts +0 -34
  157. package/src/utils/lookup-package-scope.ts +0 -97
  158. package/src/utils/parse-data-url.ts +0 -71
  159. package/src/utils/parse-module-id.ts +0 -197
  160. package/src/utils/parse-subpath.ts +0 -331
  161. package/src/utils/pattern-character.ts +0 -13
  162. package/src/utils/read-package-json.ts +0 -113
  163. package/src/utils/resolve-alias.ts +0 -224
  164. package/src/utils/resolve-aliases.ts +0 -58
  165. package/src/utils/resolve-extensions.ts +0 -33
  166. package/src/utils/resolve-module.ts +0 -181
  167. package/src/utils/resolve-modules.ts +0 -60
  168. package/src/utils/to-absolute-specifier.ts +0 -30
  169. package/src/utils/to-bare-specifier.ts +0 -211
  170. package/src/utils/to-data-url.ts +0 -42
  171. package/src/utils/to-node-url.ts +0 -27
  172. package/src/utils/to-relative-specifier.ts +0 -55
  173. package/src/utils/to-url.ts +0 -30
  174. package/src/utils/validate-assertions.ts +0 -126
  175. package/src/utils/validate-exports.ts +0 -131
@@ -1,251 +0,0 @@
1
- /**
2
- * @file findSubpath
3
- * @module mlly/utils/findSubpath
4
- */
5
-
6
- import type { FindSubpathOptions } from '#src/interfaces'
7
- import getSubpaths from '#src/internal/get-subpaths'
8
- import validateBoolean from '#src/internal/validate-boolean'
9
- import validateSet from '#src/internal/validate-set'
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 type { Exports, Imports } from '@flex-development/pkg-types'
15
- import {
16
- DOT,
17
- cast,
18
- isArray,
19
- isNIL,
20
- isObjectCurly,
21
- isString,
22
- sort,
23
- type Nilable,
24
- type Nullable,
25
- type Optional
26
- } from '@flex-development/tutils'
27
- import { URL } from 'node:url'
28
- import compareSubpaths from './compare-subpaths'
29
- import CONDITIONS from './conditions'
30
- import isExportsSugar from './is-exports-sugar'
31
- import PATTERN_CHARACTER from './pattern-character'
32
- import toURL from './to-url'
33
-
34
- /**
35
- * Finds the subpath defined in `context`, a `package.json` [`exports`][1] or
36
- * [`imports`][2] field, that maps to the given package `target`.
37
- *
38
- * Supports extensionless targets and targets without explicit `'/index'` usage.
39
- * Returns `null` if a subpath is not found.
40
- *
41
- * [1]: https://nodejs.org/api/packages.html#exports
42
- * [2]: https://nodejs.org/api/packages.html#imports
43
- *
44
- * @see {@linkcode Exports}
45
- * @see {@linkcode FindSubpathOptions}
46
- * @see {@linkcode Imports}
47
- * @see https://nodejs.org/api/packages.html#subpath-exports
48
- * @see https://nodejs.org/api/packages.html#subpath-imports
49
- *
50
- * @param {string} target - Package target to find in `context`
51
- * @param {Nilable<Exports | Imports>} context - Package context
52
- * @param {FindSubpathOptions} options - Search options
53
- * @return {Nullable<string>} Subpath defined in `context` or `null`
54
- * @throws {NodeError<Error | TypeError>}
55
- */
56
- const findSubpath = (
57
- target: string,
58
- context: Nilable<Exports | Imports>,
59
- options: FindSubpathOptions
60
- ): Nullable<string> => {
61
- const {
62
- condition = 'default',
63
- conditions = CONDITIONS,
64
- dir,
65
- internal = false,
66
- parent
67
- } = options
68
-
69
- // exit early if context is nil
70
- if (isNIL(context)) return null
71
-
72
- // ensure target is a string
73
- validateString(target, 'target')
74
-
75
- // exit early if target is an exactish match
76
- if (isString(context)) {
77
- if (target === context || target === pathe.changeExt(context, '')) {
78
- return DOT
79
- }
80
- }
81
-
82
- // ensure option schemas
83
- validateString(condition, 'options.condition')
84
- validateSet(conditions, 'options.conditions')
85
- validateURLString(dir, 'options.dir')
86
- validateBoolean(internal, 'options.internal')
87
- validateURLString(parent, 'options.parent')
88
-
89
- /**
90
- * Finds the subpath defined in `context`, a `package.json` [`exports`][1] or
91
- * [`imports`][2] field, that maps to the given package `target`.
92
- *
93
- * Returns `null` if a subpath is not found.
94
- *
95
- * [1]: https://nodejs.org/api/packages.html#exports
96
- * [2]: https://nodejs.org/api/packages.html#imports
97
- *
98
- * @param {string} target - Package target to find in `context`
99
- * @param {Nilable<Exports | Imports>} context - Package context
100
- * @param {string} [key=DOT] - Subpath in `context` being checked
101
- * @return {Nullable<string>} Subpath defined in `context` or `null`
102
- */
103
- const find = (
104
- target: string,
105
- context: Nilable<Exports | Imports>,
106
- key: string = DOT
107
- ): Nullable<string> => {
108
- /**
109
- * Subpath defined in {@linkcode context} that maps to {@linkcode target}.
110
- *
111
- * @var {Nullable<string>} subpath
112
- */
113
- let subpath: Nullable<string> = null
114
-
115
- // match target to subpath
116
- if (isArray(context) || isObjectCurly(context) || isString(context)) {
117
- /**
118
- * URL of directory containing relevant `package.json` file.
119
- *
120
- * @const {string} pkgdir
121
- */
122
- const pkgdir: string = toURL(dir).href.replace(/\/$/, '') + pathe.sep
123
-
124
- /**
125
- * URL of relevant `package.json` file.
126
- *
127
- * @const {URL} pkg
128
- */
129
- const pkg: URL = new URL('package.json', pkgdir)
130
-
131
- // convert package context to object if using exports sugar
132
- if (!internal && isExportsSugar(context, pkg, parent)) {
133
- context = cast<Record<string, Exports>>({ [key]: context })
134
- }
135
-
136
- // context is now an object
137
- context = cast<Record<string, Exports>>(context)
138
-
139
- /**
140
- * Subpaths defined in {@linkcode context}.
141
- *
142
- * **Note**: Sorted from least to greatest.
143
- *
144
- * @see {@linkcode compareSubpaths}
145
- *
146
- * @const {string[]} keys
147
- */
148
- const subpaths: string[] = sort(
149
- getSubpaths(context, internal, pkg, parent),
150
- (s1, s2) => compareSubpaths(s1, s2) * -1
151
- )
152
-
153
- // match target to subpath defined in context
154
- for (const pkgsubpath of subpaths) {
155
- /**
156
- * Current package target being checked.
157
- *
158
- * @var {Optional<Exports>} tar
159
- */
160
- let tar: Optional<Exports> = context[pkgsubpath]
161
-
162
- // find subpath
163
- switch (true) {
164
- case isArray(tar):
165
- // try matching target based first match in target array
166
- for (const item of cast<string[]>(tar)) {
167
- subpath = find(target, item, pkgsubpath)
168
- if (subpath) break
169
- }
170
-
171
- break
172
- case isObjectCurly(tar):
173
- tar = cast<Record<string, Exports>>(tar)
174
-
175
- // try matching target based on export conditions
176
- for (const property of Object.getOwnPropertyNames(tar)) {
177
- if (property === condition || conditions.has(property)) {
178
- subpath = find(target, tar[property], pkgsubpath)
179
- if (subpath) break
180
- }
181
- }
182
-
183
- break
184
- case isString(tar):
185
- tar = cast<string>(tar)
186
-
187
- /**
188
- * {@linkcode tar} without file extension.
189
- *
190
- * @const {string} tar_ne
191
- */
192
- const tar_ne: string = pathe.changeExt(tar, '')
193
-
194
- /**
195
- * {@linkcode tar_ne} without `'/index'`.
196
- *
197
- * @const {string} tar_ni
198
- */
199
- const tar_ni: string = tar_ne.replace(/\/index$/, '')
200
-
201
- /**
202
- * Index of {@linkcode PATTERN_CHARACTER} in {@linkcode tar}.
203
- *
204
- * @const {number} pattern
205
- */
206
- const pattern: number = tar.indexOf(PATTERN_CHARACTER)
207
-
208
- switch (true) {
209
- // target is an exactish match
210
- case target === tar:
211
- case target === tar_ne:
212
- case target === tar_ni && tar_ne.endsWith('/index'):
213
- case pattern === -1 && (target === tar || target === tar_ne):
214
- subpath = pkgsubpath
215
- break
216
- // pattern character => try finding best match for target
217
- case pattern !== -1 && target.startsWith(tar.slice(0, pattern)):
218
- /**
219
- * Boolean indicating if {@linkcode target} ends with the
220
- * characters after the pattern character (`*`) in
221
- * {@linkcode tar}.
222
- *
223
- * @const {boolean} match
224
- */
225
- const match: boolean =
226
- target.length >= tar.length &&
227
- tar.lastIndexOf(PATTERN_CHARACTER) === pattern &&
228
- (target.endsWith(tar.slice(pattern + 1)) ||
229
- target.endsWith(tar_ne.slice(pattern + 1)))
230
-
231
- // set subpath if match was found
232
- if (match) subpath = pkgsubpath
233
-
234
- break
235
- }
236
-
237
- break
238
- }
239
-
240
- // stop searching for subpath if subpath has been found
241
- if (subpath) break
242
- }
243
- }
244
-
245
- return subpath
246
- }
247
-
248
- return find(target, context)
249
- }
250
-
251
- export default findSubpath
@@ -1,249 +0,0 @@
1
- /**
2
- * @file getFormat
3
- * @module mlly/utils/getFormat
4
- */
5
-
6
- import { Format } from '#src/enums'
7
- import type { GetFormatOptions, PackageScope } from '#src/interfaces'
8
- import validateBoolean from '#src/internal/validate-boolean'
9
- import validateMap from '#src/internal/validate-map'
10
- import validateObject from '#src/internal/validate-object'
11
- import type { ModuleId } from '#src/types'
12
- import {
13
- ERR_UNKNOWN_FILE_EXTENSION,
14
- type NodeError
15
- } from '@flex-development/errnode'
16
- import { isBuiltin } from '@flex-development/is-builtin'
17
- import pathe, { type Ext } from '@flex-development/pathe'
18
- import {
19
- isEmptyString,
20
- isUndefined,
21
- type EmptyString,
22
- type Nilable,
23
- type Nullable,
24
- type Optional
25
- } from '@flex-development/tutils'
26
- import type { URL } from 'node:url'
27
- import EXTENSION_FORMAT_MAP from './extension-format-map'
28
- import lookupPackageScope from './lookup-package-scope'
29
- import parseDataURL from './parse-data-url'
30
- import toURL from './to-url'
31
-
32
- /**
33
- * Retrieves a module format for the given module `id`.
34
- *
35
- * ::: tip
36
- * The given module `id` should be absolute (i.e. a [`file:` URL][1] or absolute
37
- * specifier).
38
- * :::
39
- *
40
- * [1]: https://nodejs.org/api/esm.html#file-urls
41
- *
42
- * @see {@linkcode Format}
43
- * @see {@linkcode GetFormatOptions}
44
- * @see {@linkcode ModuleId}
45
- *
46
- * @async
47
- *
48
- * @param {ModuleId} id - Module id to evaluate
49
- * @param {GetFormatOptions?} [options={}] - Format retrieval options
50
- * @return {Promise<Nilable<Format>>} Module format, `null`, or `undefined`
51
- * @throws {NodeError<TypeError>}
52
- */
53
- const getFormat = async (
54
- id: ModuleId,
55
- options: GetFormatOptions = {}
56
- ): Promise<Nilable<Format>> => {
57
- const {
58
- experimental_json_modules: json_modules = true,
59
- experimental_network_imports: network_imports = false,
60
- experimental_wasm_modules: wasm_modules = false,
61
- extension_format_map = EXTENSION_FORMAT_MAP,
62
- ignore_errors = false,
63
- req = {}
64
- } = options
65
-
66
- validateBoolean(json_modules, 'options.experimental_json_modules')
67
- validateBoolean(network_imports, 'options.experimental_network_imports')
68
- validateBoolean(wasm_modules, 'options.experimental_wasm_modules')
69
- validateBoolean(ignore_errors, 'options.ignore_errors')
70
- validateMap(extension_format_map, 'options.extension_format_map')
71
- !isUndefined(req) && validateObject(req, 'options.req')
72
-
73
- /**
74
- * Module {@linkcode id} as {@linkcode URL}.
75
- *
76
- * @const {URL} url
77
- */
78
- const url: URL = toURL(id)
79
-
80
- /**
81
- * Extracts a [MIME type][1] from a {@linkcode URL} href, {@linkcode URL}
82
- * pathname, or [`Content-Type`][2] header and converts it to a module format.
83
- *
84
- * [1]: https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/MIME_types
85
- * [2]: https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Type
86
- *
87
- * @param {Nullable<string>} value - `URL` component or `content-type` header
88
- * @param {boolean} [content_type=false] - `value` is `content-type` header?
89
- * @return {Nilable<Format>} Module format, `null`, or `undefined`
90
- */
91
- const mimeToFormat = (
92
- value: Nullable<string>,
93
- content_type: boolean = false
94
- ): Nilable<Format> => {
95
- /**
96
- * Module format for {@linkcode value}.
97
- *
98
- * @var {Nilable<Format>} format
99
- */
100
- let format: Nilable<Format> = null
101
-
102
- // do nothing if value is empty
103
- /* c8 ignore next */ if (!value) return format
104
-
105
- // sanitize content-type header
106
- if (content_type) value = value.replace(/;.*/, ',')
107
-
108
- // add data: protocol to value
109
- if (!value.startsWith('data:')) value = `data:${value}`
110
-
111
- // get format based on mime type
112
- try {
113
- switch (parseDataURL(value).mime) {
114
- case 'application/javascript':
115
- case 'application/typescript':
116
- case 'text/javascript':
117
- format = Format.MODULE
118
- break
119
- case 'application/json':
120
- format = json_modules ? Format.JSON : null
121
- break
122
- case 'application/wasm':
123
- format = wasm_modules ? Format.WASM : null
124
- break
125
- default:
126
- break
127
- }
128
- } catch {
129
- format = ignore_errors ? undefined : null
130
- }
131
-
132
- return format
133
- }
134
-
135
- /**
136
- * Module format for {@linkcode id}.
137
- *
138
- * @var {Nilable<Format>} format
139
- */
140
- let format: Nilable<Format> = null
141
-
142
- // get format based on url protocol
143
- switch (url.protocol) {
144
- case 'data:':
145
- format = mimeToFormat(url.href)
146
- break
147
- case 'file:':
148
- /**
149
- * File extension of {@linkcode url.pathname}.
150
- *
151
- * @const {EmptyString | Ext}
152
- */
153
- const ext: EmptyString | Ext = pathe.extname(url.pathname)
154
-
155
- /**
156
- * Package scope result for {@linkcode url}.
157
- *
158
- * @const {Nullable<PackageScope>} scope
159
- */
160
- const scope: Nullable<PackageScope> = lookupPackageScope(url)
161
-
162
- switch (true) {
163
- // get format based on package type
164
- case scope && ext === '.js':
165
- format =
166
- scope!.pkgjson.type === Format.MODULE
167
- ? Format.MODULE
168
- : Format.COMMONJS
169
- break
170
- // get format based on file extension
171
- case extension_format_map.has(ext):
172
- format = extension_format_map.get(ext)!
173
-
174
- switch (true) {
175
- case format === Format.JSON && !json_modules:
176
- case format === Format.WASM && !wasm_modules:
177
- format = ignore_errors ? undefined : null
178
- break
179
- default:
180
- break
181
- }
182
-
183
- break
184
- // ignore file extension errors
185
- case ignore_errors:
186
- format = undefined
187
- break
188
- default:
189
- /**
190
- * Recommended fix for [`ERR_UNKNOWN_FILE_EXTENSION`][1].
191
- *
192
- * [1]: https://nodejs.org/api/errors.html#err_unknown_file_extension
193
- *
194
- * @var {Optional<string>} suggestion
195
- */
196
- let suggestion: Optional<string>
197
-
198
- // add recommended fix for ERR_UNKNOWN_FILE_EXTENSION if package is
199
- // esm-only and module id does not include file extension
200
- if (scope && scope.pkgjson.type === Format.MODULE) {
201
- if (isEmptyString(ext)) {
202
- const { pkg } = scope
203
-
204
- /**
205
- * Basename of {@linkcode url.pathname}
206
- *
207
- * @const {string} basename
208
- */
209
- const basename: string = pathe.basename(url.pathname)
210
-
211
- /**
212
- * Relative path from {@linkcode pkg} to {@linkcode url.pathname}.
213
- *
214
- * @const {string} relative
215
- */
216
- const relative: string = pathe
217
- .relative(pkg, url.pathname)
218
- .slice(1)
219
-
220
- suggestion = `Loading extensionless files is not supported inside of "type":"module" package.json contexts. The package.json file ${pkg} caused this "type":"module" context. Try changing ${url.pathname} to have a file extension. Note the "bin" field of package.json can point to a file with an extension, for example {"type":"module","bin":{"${basename}":"${relative}.js"}}`
221
- }
222
- }
223
-
224
- throw new ERR_UNKNOWN_FILE_EXTENSION(ext, url.pathname, suggestion)
225
- }
226
-
227
- break
228
- case 'http:':
229
- case 'https:':
230
- if (network_imports) {
231
- const { default: fetch } = await import('node-fetch')
232
- const { headers } = await fetch(url.href, req)
233
- format = mimeToFormat(headers.get('content-type'), true)
234
- } else {
235
- format = ignore_errors ? undefined : null
236
- }
237
-
238
- break
239
- case 'node:':
240
- if (isBuiltin(url)) format = Format.BUILTIN
241
- break
242
- default:
243
- break
244
- }
245
-
246
- return format
247
- }
248
-
249
- export default getFormat
@@ -1,144 +0,0 @@
1
- /**
2
- * @file getSource
3
- * @module mlly/utils/getSource
4
- */
5
-
6
- import { Format } from '#src/enums'
7
- import type { GetSourceOptions } from '#src/interfaces'
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 type { ModuleId } from '#src/types'
12
- import {
13
- ERR_UNSUPPORTED_ESM_URL_SCHEME,
14
- type NodeError
15
- } from '@flex-development/errnode'
16
- import { isUndefined, type Optional } from '@flex-development/tutils'
17
- import fs from 'node:fs/promises'
18
- import os from 'node:os'
19
- import type { URL } from 'node:url'
20
- import util from 'node:util'
21
- import parseDataURL from './parse-data-url'
22
- import toURL from './to-url'
23
-
24
- /**
25
- * Retrieves source code for the given module `id`.
26
- *
27
- * ::: tip
28
- * The given module `id` should be absolute (i.e. a [`file:` URL][1] or absolute
29
- * specifier).
30
- * :::
31
- *
32
- * [1]: https://nodejs.org/api/esm.html#file-urls
33
- *
34
- * @see {@linkcode GetSourceOptions}
35
- * @see {@linkcode ModuleId}
36
- * @see https://nodejs.org/docs/latest-v19.x/api/esm.html#loadurl-context-nextload
37
- *
38
- * @async
39
- *
40
- * @param {ModuleId} id - Module id to evaluate
41
- * @param {GetSourceOptions?} [options={}] - Source code retrieval options
42
- * @return {Promise<Optional<Uint8Array | string>>} Source code for `id`
43
- * @throws {NodeError} If unsupported URL scheme is encountered
44
- */
45
- const getSource = async (
46
- id: ModuleId,
47
- options: GetSourceOptions = {}
48
- ): Promise<Optional<Uint8Array | string>> => {
49
- const {
50
- experimental_network_imports: network_imports = false,
51
- format,
52
- ignore_errors = false,
53
- req = {}
54
- } = options
55
-
56
- validateBoolean(network_imports, 'options.experimental_network_imports')
57
- !isUndefined(format) && validateString(format, 'options.format')
58
- validateBoolean(ignore_errors, 'options.ignore_errors')
59
- !isUndefined(req) && validateObject(req, 'options.req')
60
-
61
- // exit early if format is Format.BUILTIN
62
- if (format === Format.BUILTIN) return undefined
63
-
64
- /**
65
- * Module {@linkcode id} as {@linkcode URL}.
66
- *
67
- * @const {URL} url
68
- */
69
- const url: URL = toURL(id)
70
-
71
- /**
72
- * [`ERR_UNSUPPORTED_ESM_URL_SCHEME`][1] check.
73
- *
74
- * [1]: https://nodejs.org/api/errors.html#err_unsupported_esm_url_scheme
75
- *
76
- * @var {boolean} err
77
- */
78
- let err: boolean = false
79
-
80
- /**
81
- * Source code for {@linkcode id}.
82
- *
83
- * @var {Optional<Uint8Array | string>} source
84
- */
85
- let source: Optional<Uint8Array | string> = ''
86
-
87
- // get source code based on url protocol
88
- switch (url.protocol) {
89
- case 'data:':
90
- const { base64, data } = parseDataURL(url)
91
-
92
- /**
93
- * Buffer encoding used to create a {@linkcode Buffer} instance from
94
- * {@linkcode data}.
95
- *
96
- * @const {BufferEncoding} encoding
97
- */
98
- const encoding: BufferEncoding = base64 ? 'base64' : 'utf8'
99
-
100
- source = Buffer.from(decodeURIComponent(data), encoding).toString()
101
- break
102
- case 'file:':
103
- source = await fs.readFile(url, 'utf8')
104
- break
105
- case 'http:':
106
- case 'https:':
107
- if (network_imports) {
108
- const { default: fetch } = await import('node-fetch')
109
- source = await (await fetch(url.href, req)).text()
110
- } else {
111
- err = true
112
- }
113
-
114
- break
115
- case 'node:':
116
- source = undefined
117
- break
118
- default:
119
- err = true
120
- }
121
-
122
- // throw if unsupported url scheme was encountered
123
- if (!ignore_errors && err) {
124
- /**
125
- * Supported URL schemes.
126
- *
127
- * @const {string[]} schemes
128
- */
129
- const schemes: string[] = ['data', 'file']
130
-
131
- // update supported schemes if support for network based modules is enabled
132
- if (network_imports) schemes.push('http', 'https')
133
-
134
- throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(
135
- url,
136
- schemes,
137
- os.platform() === 'win32'
138
- )
139
- }
140
-
141
- return format === Format.WASM ? new util.TextEncoder().encode(source) : source
142
- }
143
-
144
- export default getSource
@@ -1,44 +0,0 @@
1
- /**
2
- * @file hasCJSSyntax
3
- * @module mlly/utils/hasCJSSyntax
4
- */
5
-
6
- import validateString from '#src/internal/validate-string'
7
- import type { NodeError } from '@flex-development/errnode'
8
-
9
- /**
10
- * Detects if `code` contains CommonJS syntax. Ignores matches in comments.
11
- *
12
- * Syntax patterns:
13
- *
14
- * - `__dirname`
15
- * - `__filename`
16
- * - `await import`
17
- * - `exports`
18
- * - `module.exports`
19
- * - `require`
20
- * - `require.*`
21
- *
22
- * @see https://regex101.com/r/Co77SJ
23
- *
24
- * @param {string} code - Code to evaluate
25
- * @return {boolean} `true` if `code` contains cjs syntax, `false` otherwise
26
- * @throws {NodeError<TypeError>} If `code` is not a string
27
- */
28
- const hasCJSSyntax = (code: string): boolean => {
29
- validateString(code, 'code')
30
-
31
- /**
32
- * CommonJS syntax regex.
33
- *
34
- * @see https://regex101.com/r/Co77SJ
35
- *
36
- * @const {RegExp} CJS_SYNTAX_REGEX
37
- */
38
- const CJS_SYNTAX_REGEX: RegExp =
39
- /(?<!(?:\/\/|\*).*)((?:module\.)?exports(?:\.\w+|(?<!\s+=))|require(?=\(.)|require\.\w+|__dirname|__filename|await import)/gm
40
-
41
- return !!code.match(CJS_SYNTAX_REGEX)
42
- }
43
-
44
- export default hasCJSSyntax