@jsenv/core 23.7.1 → 23.8.0

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 (34) hide show
  1. package/dist/jsenv_browser_system.js.map +1 -1
  2. package/dist/jsenv_compile_proxy.js.map +1 -1
  3. package/dist/jsenv_exploring_redirector.js.map +1 -1
  4. package/dist/jsenv_toolbar.js +0 -2
  5. package/dist/jsenv_toolbar.js.map +3 -3
  6. package/package.json +2 -2
  7. package/src/buildProject.js +300 -300
  8. package/src/execute.js +184 -184
  9. package/src/internal/browser-launcher/jsenv-browser-system.js +199 -199
  10. package/src/internal/compiling/babel_plugin_import_assertions.js +121 -100
  11. package/src/internal/compiling/babel_plugin_import_metadata.js +22 -0
  12. package/src/internal/compiling/babel_plugin_import_visitor.js +84 -0
  13. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +268 -265
  14. package/src/internal/compiling/compile-directory/updateMeta.js +154 -150
  15. package/src/internal/compiling/compile-directory/validateCache.js +265 -265
  16. package/src/internal/compiling/compileFile.js +215 -194
  17. package/src/internal/compiling/compileHtml.js +550 -494
  18. package/src/internal/compiling/createCompiledFileService.js +291 -290
  19. package/src/internal/compiling/html_source_file_service.js +403 -379
  20. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +270 -269
  21. package/src/internal/compiling/jsenvCompilerForHtml.js +300 -293
  22. package/src/internal/compiling/startCompileServer.js +1048 -1052
  23. package/src/internal/compiling/transformResultToCompilationResult.js +220 -217
  24. package/src/internal/executing/executePlan.js +183 -183
  25. package/src/internal/executing/launchAndExecute.js +458 -458
  26. package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +246 -246
  27. package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +112 -112
  28. package/src/internal/toolbar/toolbar.main.css +196 -188
  29. package/src/internal/toolbar/toolbar.main.js +227 -228
  30. package/src/internal/url_conversion.js +317 -317
  31. package/src/startExploring.js +309 -309
  32. package/src/internal/compiling/babel_plugin_transform_import_specifier.js +0 -86
  33. package/src/internal/toolbar/animation/animation.css +0 -5
  34. package/src/internal/toolbar/variant/variant.css +0 -3
@@ -1,199 +1,199 @@
1
- /* eslint-env browser */
2
-
3
- import { unevalException } from "../unevalException.js"
4
- import { createBrowserRuntime } from "../runtime/createBrowserRuntime/createBrowserRuntime.js"
5
- import { installBrowserErrorStackRemapping } from "../error-stack-remapping/installBrowserErrorStackRemapping.js"
6
- import { fetchUrl } from "../browser-utils/fetch-browser.js"
7
- import { fetchAndEvalUsingFetch } from "../browser-utils/fetchAndEvalUsingFetch.js"
8
- import { memoize } from "../memoize.js"
9
-
10
- const getNavigationStartTime = () => {
11
- try {
12
- return window.performance.timing.navigationStart
13
- } catch (e) {
14
- return Date.now()
15
- }
16
- }
17
-
18
- const navigationStartTime = getNavigationStartTime()
19
-
20
- const readyPromise = new Promise((resolve) => {
21
- if (document.readyState === "complete") {
22
- resolve()
23
- } else {
24
- const loadCallback = () => {
25
- window.removeEventListener("load", loadCallback)
26
- resolve()
27
- }
28
- window.addEventListener("load", loadCallback)
29
- }
30
- })
31
-
32
- const fileExecutionMap = {}
33
-
34
- const executionResultPromise = readyPromise.then(async () => {
35
- const fileExecutionResultMap = {}
36
- const fileExecutionResultPromises = []
37
- let status = "completed"
38
- let exceptionSource = ""
39
- Object.keys(fileExecutionMap).forEach((key) => {
40
- fileExecutionResultMap[key] = null // to get always same order for Object.keys(executionResult)
41
- const fileExecutionResultPromise = fileExecutionMap[key]
42
- fileExecutionResultPromises.push(fileExecutionResultPromise)
43
- fileExecutionResultPromise.then((fileExecutionResult) => {
44
- fileExecutionResultMap[key] = fileExecutionResult
45
- if (fileExecutionResult.status === "errored") {
46
- status = "errored"
47
- exceptionSource = fileExecutionResult.exceptionSource
48
- }
49
- })
50
- })
51
- await Promise.all(fileExecutionResultPromises)
52
-
53
- return {
54
- status,
55
- ...(status === "errored" ? { exceptionSource } : {}),
56
- startTime: navigationStartTime,
57
- endTime: Date.now(),
58
- fileExecutionResultMap,
59
- }
60
- })
61
-
62
- const executeFileUsingDynamicImport = async (
63
- specifier,
64
- identifier = specifier,
65
- ) => {
66
- const { currentScript } = document
67
- const fileExecutionResultPromise = (async () => {
68
- try {
69
- const url = new URL(specifier, document.location.href).href
70
- performance.mark(`jsenv_file_import_start`)
71
- const namespace = await import(url)
72
- performance.measure(`jsenv_file_import`, `jsenv_file_import_start`)
73
- const executionResult = {
74
- status: "completed",
75
- namespace,
76
- }
77
- return executionResult
78
- } catch (e) {
79
- performance.measure(`jsenv_file_import`, `jsenv_file_import_start`)
80
- const executionResult = {
81
- status: "errored",
82
- exceptionSource: unevalException(e),
83
- }
84
- onExecutionError(executionResult, { currentScript })
85
- return executionResult
86
- }
87
- })()
88
- fileExecutionMap[identifier] = fileExecutionResultPromise
89
- return fileExecutionResultPromise
90
- }
91
-
92
- const executeFileUsingSystemJs = (specifier) => {
93
- // si on a déja importer ce fichier ??
94
- // if (specifier in fileExecutionMap) {
95
-
96
- // }
97
-
98
- const { currentScript } = document
99
-
100
- const fileExecutionResultPromise = (async () => {
101
- const browserRuntime = await getBrowserRuntime()
102
- const executionResult = await browserRuntime.executeFile(specifier, {
103
- measurePerformance: true,
104
- collectPerformance: true,
105
- })
106
- if (executionResult.status === "errored") {
107
- onExecutionError(executionResult, { currentScript })
108
- }
109
- return executionResult
110
- })()
111
- fileExecutionMap[specifier] = fileExecutionResultPromise
112
- return fileExecutionResultPromise
113
- }
114
-
115
- const onExecutionError = (executionResult, { currentScript }) => {
116
- // eslint-disable-next-line no-eval
117
- const originalError = window.eval(executionResult.exceptionSource)
118
- if (originalError.code === "NETWORK_FAILURE") {
119
- if (currentScript) {
120
- const errorEvent = new Event("error")
121
- currentScript.dispatchEvent(errorEvent)
122
- }
123
- } else {
124
- const { parsingError } = originalError
125
- const globalErrorEvent = new Event("error")
126
- if (parsingError) {
127
- globalErrorEvent.filename = parsingError.filename
128
- globalErrorEvent.lineno = parsingError.lineNumber
129
- globalErrorEvent.message = parsingError.message
130
- globalErrorEvent.colno = parsingError.columnNumber
131
- } else {
132
- globalErrorEvent.filename = originalError.filename
133
- globalErrorEvent.lineno = originalError.lineno
134
- globalErrorEvent.message = originalError.message
135
- globalErrorEvent.colno = originalError.columnno
136
- }
137
- window.dispatchEvent(globalErrorEvent)
138
- }
139
- }
140
-
141
- const getBrowserRuntime = memoize(async () => {
142
- const compileServerOrigin = document.location.origin
143
- const compileMetaResponse = await fetchUrl(
144
- `${compileServerOrigin}/.jsenv/__compile_server_meta__.json`,
145
- )
146
- const compileMeta = await compileMetaResponse.json()
147
- const { outDirectoryRelativeUrl, errorStackRemapping } = compileMeta
148
- const outDirectoryUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`
149
- const afterOutDirectory = document.location.href.slice(outDirectoryUrl.length)
150
- const parts = afterOutDirectory.split("/")
151
- const compileId = parts[0]
152
-
153
- const browserRuntime = await createBrowserRuntime({
154
- compileServerOrigin,
155
- outDirectoryRelativeUrl,
156
- compileId,
157
- })
158
-
159
- if (errorStackRemapping && Error.captureStackTrace) {
160
- const { sourcemapMainFileRelativeUrl, sourcemapMappingFileRelativeUrl } =
161
- compileMeta
162
-
163
- await fetchAndEvalUsingFetch(
164
- `${compileServerOrigin}/${sourcemapMainFileRelativeUrl}`,
165
- )
166
- const { SourceMapConsumer } = window.sourceMap
167
- SourceMapConsumer.initialize({
168
- "lib/mappings.wasm": `${compileServerOrigin}/${sourcemapMappingFileRelativeUrl}`,
169
- })
170
- const { getErrorOriginalStackString } = installBrowserErrorStackRemapping({
171
- SourceMapConsumer,
172
- })
173
-
174
- const errorTransform = async (error) => {
175
- // code can throw something else than an error
176
- // in that case return it unchanged
177
- if (!error || !(error instanceof Error)) return error
178
- const originalStack = await getErrorOriginalStackString(error)
179
- error.stack = originalStack
180
- return error
181
- }
182
-
183
- const executeFile = browserRuntime.executeFile
184
- browserRuntime.executeFile = (file, options = {}) => {
185
- return executeFile(file, { errorTransform, ...options })
186
- }
187
- }
188
-
189
- return browserRuntime
190
- })
191
-
192
- const livereloadingCallbacks = {}
193
-
194
- window.__jsenv__ = {
195
- livereloadingCallbacks,
196
- executionResultPromise,
197
- executeFileUsingDynamicImport,
198
- executeFileUsingSystemJs,
199
- }
1
+ /* eslint-env browser */
2
+
3
+ import { unevalException } from "../unevalException.js"
4
+ import { createBrowserRuntime } from "../runtime/createBrowserRuntime/createBrowserRuntime.js"
5
+ import { installBrowserErrorStackRemapping } from "../error-stack-remapping/installBrowserErrorStackRemapping.js"
6
+ import { fetchUrl } from "../browser-utils/fetch-browser.js"
7
+ import { fetchAndEvalUsingFetch } from "../browser-utils/fetchAndEvalUsingFetch.js"
8
+ import { memoize } from "../memoize.js"
9
+
10
+ const getNavigationStartTime = () => {
11
+ try {
12
+ return window.performance.timing.navigationStart
13
+ } catch (e) {
14
+ return Date.now()
15
+ }
16
+ }
17
+
18
+ const navigationStartTime = getNavigationStartTime()
19
+
20
+ const readyPromise = new Promise((resolve) => {
21
+ if (document.readyState === "complete") {
22
+ resolve()
23
+ } else {
24
+ const loadCallback = () => {
25
+ window.removeEventListener("load", loadCallback)
26
+ resolve()
27
+ }
28
+ window.addEventListener("load", loadCallback)
29
+ }
30
+ })
31
+
32
+ const fileExecutionMap = {}
33
+
34
+ const executionResultPromise = readyPromise.then(async () => {
35
+ const fileExecutionResultMap = {}
36
+ const fileExecutionResultPromises = []
37
+ let status = "completed"
38
+ let exceptionSource = ""
39
+ Object.keys(fileExecutionMap).forEach((key) => {
40
+ fileExecutionResultMap[key] = null // to get always same order for Object.keys(executionResult)
41
+ const fileExecutionResultPromise = fileExecutionMap[key]
42
+ fileExecutionResultPromises.push(fileExecutionResultPromise)
43
+ fileExecutionResultPromise.then((fileExecutionResult) => {
44
+ fileExecutionResultMap[key] = fileExecutionResult
45
+ if (fileExecutionResult.status === "errored") {
46
+ status = "errored"
47
+ exceptionSource = fileExecutionResult.exceptionSource
48
+ }
49
+ })
50
+ })
51
+ await Promise.all(fileExecutionResultPromises)
52
+
53
+ return {
54
+ status,
55
+ ...(status === "errored" ? { exceptionSource } : {}),
56
+ startTime: navigationStartTime,
57
+ endTime: Date.now(),
58
+ fileExecutionResultMap,
59
+ }
60
+ })
61
+
62
+ const executeFileUsingDynamicImport = async (
63
+ specifier,
64
+ identifier = specifier,
65
+ ) => {
66
+ const { currentScript } = document
67
+ const fileExecutionResultPromise = (async () => {
68
+ try {
69
+ const url = new URL(specifier, document.location.href).href
70
+ performance.mark(`jsenv_file_import_start`)
71
+ const namespace = await import(url)
72
+ performance.measure(`jsenv_file_import`, `jsenv_file_import_start`)
73
+ const executionResult = {
74
+ status: "completed",
75
+ namespace,
76
+ }
77
+ return executionResult
78
+ } catch (e) {
79
+ performance.measure(`jsenv_file_import`, `jsenv_file_import_start`)
80
+ const executionResult = {
81
+ status: "errored",
82
+ exceptionSource: unevalException(e),
83
+ }
84
+ onExecutionError(executionResult, { currentScript })
85
+ return executionResult
86
+ }
87
+ })()
88
+ fileExecutionMap[identifier] = fileExecutionResultPromise
89
+ return fileExecutionResultPromise
90
+ }
91
+
92
+ const executeFileUsingSystemJs = (specifier) => {
93
+ // si on a déja importer ce fichier ??
94
+ // if (specifier in fileExecutionMap) {
95
+
96
+ // }
97
+
98
+ const { currentScript } = document
99
+
100
+ const fileExecutionResultPromise = (async () => {
101
+ const browserRuntime = await getBrowserRuntime()
102
+ const executionResult = await browserRuntime.executeFile(specifier, {
103
+ measurePerformance: true,
104
+ collectPerformance: true,
105
+ })
106
+ if (executionResult.status === "errored") {
107
+ onExecutionError(executionResult, { currentScript })
108
+ }
109
+ return executionResult
110
+ })()
111
+ fileExecutionMap[specifier] = fileExecutionResultPromise
112
+ return fileExecutionResultPromise
113
+ }
114
+
115
+ const onExecutionError = (executionResult, { currentScript }) => {
116
+ // eslint-disable-next-line no-eval
117
+ const originalError = window.eval(executionResult.exceptionSource)
118
+ if (originalError.code === "NETWORK_FAILURE") {
119
+ if (currentScript) {
120
+ const errorEvent = new Event("error")
121
+ currentScript.dispatchEvent(errorEvent)
122
+ }
123
+ } else {
124
+ const { parsingError } = originalError
125
+ const globalErrorEvent = new Event("error")
126
+ if (parsingError) {
127
+ globalErrorEvent.filename = parsingError.filename
128
+ globalErrorEvent.lineno = parsingError.lineNumber
129
+ globalErrorEvent.message = parsingError.message
130
+ globalErrorEvent.colno = parsingError.columnNumber
131
+ } else {
132
+ globalErrorEvent.filename = originalError.filename
133
+ globalErrorEvent.lineno = originalError.lineno
134
+ globalErrorEvent.message = originalError.message
135
+ globalErrorEvent.colno = originalError.columnno
136
+ }
137
+ window.dispatchEvent(globalErrorEvent)
138
+ }
139
+ }
140
+
141
+ const getBrowserRuntime = memoize(async () => {
142
+ const compileServerOrigin = document.location.origin
143
+ const compileMetaResponse = await fetchUrl(
144
+ `${compileServerOrigin}/.jsenv/__compile_server_meta__.json`,
145
+ )
146
+ const compileMeta = await compileMetaResponse.json()
147
+ const { outDirectoryRelativeUrl, errorStackRemapping } = compileMeta
148
+ const outDirectoryUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`
149
+ const afterOutDirectory = document.location.href.slice(outDirectoryUrl.length)
150
+ const parts = afterOutDirectory.split("/")
151
+ const compileId = parts[0]
152
+
153
+ const browserRuntime = await createBrowserRuntime({
154
+ compileServerOrigin,
155
+ outDirectoryRelativeUrl,
156
+ compileId,
157
+ })
158
+
159
+ if (errorStackRemapping && Error.captureStackTrace) {
160
+ const { sourcemapMainFileRelativeUrl, sourcemapMappingFileRelativeUrl } =
161
+ compileMeta
162
+
163
+ await fetchAndEvalUsingFetch(
164
+ `${compileServerOrigin}/${sourcemapMainFileRelativeUrl}`,
165
+ )
166
+ const { SourceMapConsumer } = window.sourceMap
167
+ SourceMapConsumer.initialize({
168
+ "lib/mappings.wasm": `${compileServerOrigin}/${sourcemapMappingFileRelativeUrl}`,
169
+ })
170
+ const { getErrorOriginalStackString } = installBrowserErrorStackRemapping({
171
+ SourceMapConsumer,
172
+ })
173
+
174
+ const errorTransform = async (error) => {
175
+ // code can throw something else than an error
176
+ // in that case return it unchanged
177
+ if (!error || !(error instanceof Error)) return error
178
+ const originalStack = await getErrorOriginalStackString(error)
179
+ error.stack = originalStack
180
+ return error
181
+ }
182
+
183
+ const executeFile = browserRuntime.executeFile
184
+ browserRuntime.executeFile = (file, options = {}) => {
185
+ return executeFile(file, { errorTransform, ...options })
186
+ }
187
+ }
188
+
189
+ return browserRuntime
190
+ })
191
+
192
+ const livereloadingCallbacks = {}
193
+
194
+ window.__jsenv__ = {
195
+ livereloadingCallbacks,
196
+ executionResultPromise,
197
+ executeFileUsingDynamicImport,
198
+ executeFileUsingSystemJs,
199
+ }
@@ -1,100 +1,121 @@
1
- import { urlToRelativeUrl } from "@jsenv/filesystem"
2
-
3
- import { setUrlSearchParamsDescriptor } from "@jsenv/core/src/internal/url_utils.js"
4
- import { babelPluginTransformImportSpecifier } from "./babel_plugin_transform_import_specifier.js"
5
-
6
- export const babelPluginImportAssertions = (
7
- babel,
8
- { transformJson = true, transformCss = true },
9
- ) => {
10
- return {
11
- ...babelPluginTransformImportSpecifier(babel, {
12
- // During the build we throw when for import call expression where
13
- // sepcifier or type is dynamic.
14
- // Here there is no strong need to throw because keeping the source code intact
15
- // will throw an error when browser will execute the code
16
- transformImportSpecifier: ({ specifier, path }) => {
17
- const importPath = path.parentPath
18
- const importNode = importPath.node
19
- let assertionsDescriptor
20
- if (importNode.type === "CallExpression") {
21
- const args = importNode.arguments
22
- const secondArg = args[1]
23
- if (!secondArg) {
24
- return specifier
25
- }
26
-
27
- const { properties } = secondArg
28
- const assertProperty = properties.find((property) => {
29
- return property.key.name === "assert"
30
- })
31
- if (!assertProperty) {
32
- return specifier
33
- }
34
-
35
- const assertProperties = assertProperty.value.properties
36
- const typePropertyNode = assertProperties.find((property) => {
37
- return property.key.name === "type"
38
- })
39
- if (!typePropertyNode) {
40
- return specifier
41
- }
42
-
43
- const typePropertyValue = typePropertyNode.value
44
- if (typePropertyValue.type !== "StringLiteral") {
45
- return specifier
46
- }
47
-
48
- assertionsDescriptor = {
49
- type: typePropertyValue.value,
50
- }
51
- } else {
52
- assertionsDescriptor = getImportAssertionsDescriptor(
53
- importPath.node.assertions,
54
- )
55
- }
56
-
57
- const { type } = assertionsDescriptor
58
- if (type === "json" && transformJson) {
59
- return forceImportTypeOnSpecifier(specifier, "json")
60
- }
61
-
62
- if (type === "css" && transformCss) {
63
- return forceImportTypeOnSpecifier(specifier, "css")
64
- }
65
-
66
- return specifier
67
- },
68
- }),
69
-
70
- name: "transform-import-assertions",
71
- }
72
- }
73
-
74
- const getImportAssertionsDescriptor = (importAssertions) => {
75
- const importAssertionsDescriptor = {}
76
- if (importAssertions) {
77
- importAssertions.forEach((importAssertion) => {
78
- importAssertionsDescriptor[importAssertion.key.name] =
79
- importAssertion.value.value
80
- })
81
- }
82
- return importAssertionsDescriptor
83
- }
84
-
85
- const forceImportTypeOnSpecifier = (specifier, importType) => {
86
- const fakeOrigin = "http://jsenv.com"
87
- const url = new URL(specifier, fakeOrigin)
88
- const urlWithImportType = setUrlSearchParamsDescriptor(url, {
89
- import_type: importType,
90
- })
91
- if (urlWithImportType.startsWith(fakeOrigin)) {
92
- // specifier was relative
93
- const specifierWithImportType = urlToRelativeUrl(
94
- urlWithImportType,
95
- fakeOrigin,
96
- )
97
- return `./${specifierWithImportType}`
98
- }
99
- return urlWithImportType
100
- }
1
+ import { urlToRelativeUrl } from "@jsenv/filesystem"
2
+
3
+ import { setUrlSearchParamsDescriptor } from "@jsenv/core/src/internal/url_utils.js"
4
+ import { babelPluginImportVisitor } from "./babel_plugin_import_visitor.js"
5
+
6
+ export const babelPluginImportAssertions = (
7
+ babel,
8
+ { transformJson = true, transformCss = true },
9
+ ) => {
10
+ return {
11
+ ...babelPluginImportVisitor(
12
+ babel,
13
+ // During the build we throw when for import call expression where
14
+ // sepcifier or type is dynamic.
15
+ // Here there is no strong need to throw because keeping the source code intact
16
+ // will throw an error when browser will execute the code
17
+ ({ importPath, specifierPath }) => {
18
+ const importNode = importPath.node
19
+ let assertionsDescriptor
20
+ if (importNode.type === "CallExpression") {
21
+ const args = importNode.arguments
22
+ const secondArg = args[1]
23
+ if (!secondArg) {
24
+ return
25
+ }
26
+
27
+ const { properties } = secondArg
28
+ const assertProperty = properties.find((property) => {
29
+ return property.key.name === "assert"
30
+ })
31
+ if (!assertProperty) {
32
+ return
33
+ }
34
+
35
+ const assertProperties = assertProperty.value.properties
36
+ const typePropertyNode = assertProperties.find((property) => {
37
+ return property.key.name === "type"
38
+ })
39
+ if (!typePropertyNode) {
40
+ return
41
+ }
42
+
43
+ const typePropertyValue = typePropertyNode.value
44
+ if (typePropertyValue.type !== "StringLiteral") {
45
+ return
46
+ }
47
+
48
+ assertionsDescriptor = {
49
+ type: typePropertyValue.value,
50
+ }
51
+ } else {
52
+ assertionsDescriptor = getImportAssertionsDescriptor(
53
+ importPath.node.assertions,
54
+ )
55
+ }
56
+
57
+ const { type } = assertionsDescriptor
58
+ if (type === "json" && transformJson) {
59
+ forceImportTypeOnSpecifier({
60
+ specifierPath,
61
+ babel,
62
+ importType: "json",
63
+ })
64
+ return
65
+ }
66
+
67
+ if (type === "css" && transformCss) {
68
+ forceImportTypeOnSpecifier({
69
+ specifierPath,
70
+ babel,
71
+ importType: "css",
72
+ })
73
+ return
74
+ }
75
+ },
76
+ ),
77
+ name: "transform-import-assertions",
78
+ }
79
+ }
80
+
81
+ const getImportAssertionsDescriptor = (importAssertions) => {
82
+ const importAssertionsDescriptor = {}
83
+ if (importAssertions) {
84
+ importAssertions.forEach((importAssertion) => {
85
+ importAssertionsDescriptor[importAssertion.key.name] =
86
+ importAssertion.value.value
87
+ })
88
+ }
89
+ return importAssertionsDescriptor
90
+ }
91
+
92
+ const forceImportTypeOnSpecifier = ({ specifierPath, babel, importType }) => {
93
+ const specifier = specifierPath.node.value
94
+ const fakeOrigin = "http://jsenv.com"
95
+ const url = new URL(specifier, fakeOrigin)
96
+ const urlWithImportType = setUrlSearchParamsDescriptor(url, {
97
+ import_type: importType,
98
+ })
99
+ if (urlWithImportType.startsWith(fakeOrigin)) {
100
+ // specifier was relative
101
+ const specifierWithImportType = urlToRelativeUrl(
102
+ urlWithImportType,
103
+ fakeOrigin,
104
+ )
105
+
106
+ replaceSpecifierUsingBabel(`./${specifierWithImportType}`, {
107
+ specifierPath,
108
+ babel,
109
+ })
110
+ return
111
+ }
112
+
113
+ replaceSpecifierUsingBabel(urlWithImportType, {
114
+ specifierPath,
115
+ babel,
116
+ })
117
+ }
118
+
119
+ const replaceSpecifierUsingBabel = (value, { specifierPath, babel }) => {
120
+ specifierPath.replaceWith(babel.types.stringLiteral(value))
121
+ }
@@ -0,0 +1,22 @@
1
+ import { babelPluginImportVisitor } from "./babel_plugin_import_visitor.js"
2
+
3
+ export const babelPluginImportMetadata = (babel) => {
4
+ return {
5
+ ...babelPluginImportVisitor(
6
+ babel,
7
+ // During the build we throw when for import call expression where
8
+ // sepcifier or type is dynamic.
9
+ // Here there is no strong need to throw because keeping the source code intact
10
+ // will throw an error when browser will execute the code
11
+ ({ state, specifierPath }) => {
12
+ const { metadata } = state.file
13
+
14
+ metadata.dependencies = [
15
+ ...(metadata.dependencies ? metadata.dependencies : []),
16
+ specifierPath.node.value,
17
+ ]
18
+ },
19
+ ),
20
+ name: "import-metadata",
21
+ }
22
+ }