@jsenv/core 32.0.1 → 32.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "32.0.1",
3
+ "version": "32.1.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -69,16 +69,16 @@
69
69
  "@jsenv/abort": "4.2.4",
70
70
  "@jsenv/ast": "3.0.3",
71
71
  "@jsenv/babel-plugins": "1.1.5",
72
- "@jsenv/filesystem": "4.2.1",
72
+ "@jsenv/filesystem": "4.2.2",
73
73
  "@jsenv/importmap": "1.2.1",
74
74
  "@jsenv/integrity": "0.0.1",
75
75
  "@jsenv/log": "3.3.4",
76
76
  "@jsenv/node-esm-resolution": "1.0.1",
77
- "@jsenv/plugin-bundling": "2.1.1",
78
- "@jsenv/server": "15.0.1",
77
+ "@jsenv/plugin-bundling": "2.1.2",
78
+ "@jsenv/server": "15.0.2",
79
79
  "@jsenv/sourcemap": "1.0.9",
80
80
  "@jsenv/uneval": "1.6.0",
81
- "@jsenv/url-meta": "8.0.0",
81
+ "@jsenv/url-meta": "8.1.0",
82
82
  "@jsenv/urls": "1.2.8",
83
83
  "@jsenv/utils": "2.0.1",
84
84
  "@paralleldrive/cuid2": "2.2.0",
@@ -112,7 +112,7 @@
112
112
  "eslint-plugin-html": "7.1.0",
113
113
  "eslint-plugin-import": "2.27.5",
114
114
  "eslint-plugin-react": "7.32.2",
115
- "playwright": "1.31.2",
116
- "prettier": "2.8.6"
115
+ "playwright": "1.32.1",
116
+ "prettier": "2.8.7"
117
117
  }
118
118
  }
@@ -53,7 +53,7 @@ import {
53
53
  findHtmlNode,
54
54
  } from "@jsenv/ast"
55
55
 
56
- import { determineJsenvInternalDirectoryUrl } from "../jsenv_internal_directory.js"
56
+ import { lookupPackageDirectory } from "../lookup_package_directory.js"
57
57
  import { watchSourceFiles } from "../watch_source_files.js"
58
58
  import { createUrlGraph } from "../kitchen/url_graph.js"
59
59
  import { createKitchen } from "../kitchen/kitchen.js"
@@ -153,7 +153,7 @@ export const build = async ({
153
153
 
154
154
  directoryToClean,
155
155
  writeOnFileSystem = true,
156
- writeGeneratedFiles = false,
156
+ outDirectoryUrl,
157
157
  assetManifest = versioningMethod === "filename",
158
158
  assetManifestFileRelativeUrl = "asset-manifest.json",
159
159
  ...rest
@@ -170,6 +170,21 @@ export const build = async ({
170
170
  sourceDirectoryUrl,
171
171
  "sourceDirectoryUrl",
172
172
  )
173
+ buildDirectoryUrl = assertAndNormalizeDirectoryUrl(
174
+ buildDirectoryUrl,
175
+ "buildDirectoryUrl",
176
+ )
177
+ if (outDirectoryUrl === undefined) {
178
+ const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl)
179
+ if (packageDirectoryUrl) {
180
+ outDirectoryUrl = `${packageDirectoryUrl}.jsenv/`
181
+ }
182
+ } else {
183
+ outDirectoryUrl = assertAndNormalizeDirectoryUrl(
184
+ outDirectoryUrl,
185
+ "outDirectoryUrl",
186
+ )
187
+ }
173
188
 
174
189
  if (typeof entryPoints !== "object" || entryPoints === null) {
175
190
  throw new TypeError(`entryPoints must be an object, got ${entryPoints}`)
@@ -193,10 +208,6 @@ export const build = async ({
193
208
  )
194
209
  }
195
210
  })
196
- buildDirectoryUrl = assertAndNormalizeDirectoryUrl(
197
- buildDirectoryUrl,
198
- "buildDirectoryUrl",
199
- )
200
211
  if (!["filename", "search_param"].includes(versioningMethod)) {
201
212
  throw new TypeError(
202
213
  `versioningMethod must be "filename" or "search_param", got ${versioning}`,
@@ -227,8 +238,6 @@ export const build = async ({
227
238
  directoryToClean = new URL(assetsDirectory, buildDirectoryUrl).href
228
239
  }
229
240
  }
230
- const jsenvInternalDirectoryUrl =
231
- determineJsenvInternalDirectoryUrl(sourceDirectoryUrl)
232
241
 
233
242
  const asFormattedBuildUrl = (generatedUrl, reference) => {
234
243
  if (base === "./") {
@@ -299,7 +308,6 @@ build ${entryPointKeys.length} entry points`)
299
308
  signal,
300
309
  logLevel,
301
310
  rootDirectoryUrl: sourceDirectoryUrl,
302
- jsenvInternalDirectoryUrl,
303
311
  urlGraph: rawGraph,
304
312
  build: true,
305
313
  runtimeCompat,
@@ -342,8 +350,9 @@ build ${entryPointKeys.length} entry points`)
342
350
  ],
343
351
  sourcemaps,
344
352
  sourcemapsSourcesContent,
345
- writeGeneratedFiles,
346
- outDirectoryUrl: new URL("build/", jsenvInternalDirectoryUrl),
353
+ outDirectoryUrl: outDirectoryUrl
354
+ ? new URL("build/", outDirectoryUrl)
355
+ : undefined,
347
356
  })
348
357
 
349
358
  const buildUrlsGenerator = createBuildUrlsGenerator({
@@ -373,7 +382,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
373
382
  const finalGraphKitchen = createKitchen({
374
383
  logLevel,
375
384
  rootDirectoryUrl: buildDirectoryUrl,
376
- jsenvInternalDirectoryUrl,
377
385
  urlGraph: finalGraph,
378
386
  build: true,
379
387
  runtimeCompat,
@@ -663,8 +671,9 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
663
671
  sourcemaps,
664
672
  sourcemapsSourcesContent,
665
673
  sourcemapsSourcesRelative: !versioning,
666
- writeGeneratedFiles,
667
- outDirectoryUrl: new URL("postbuild/", jsenvInternalDirectoryUrl),
674
+ outDirectoryUrl: outDirectoryUrl
675
+ ? new URL("postbuild/", outDirectoryUrl)
676
+ : undefined,
668
677
  })
669
678
  const finalEntryUrls = []
670
679
 
@@ -673,8 +682,8 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
673
682
  disabled: logger.levels.debug || !logger.levels.info,
674
683
  })
675
684
  try {
676
- if (writeGeneratedFiles) {
677
- await ensureEmptyDirectory(new URL(`build/`, sourceDirectoryUrl))
685
+ if (outDirectoryUrl) {
686
+ await ensureEmptyDirectory(new URL(`build/`, outDirectoryUrl))
678
687
  }
679
688
  const rawUrlGraphLoader = createUrlGraphLoader(
680
689
  rawGraphKitchen.kitchenContext,
@@ -918,10 +927,8 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
918
927
  disabled: logger.levels.debug || !logger.levels.info,
919
928
  })
920
929
  try {
921
- if (writeGeneratedFiles) {
922
- await ensureEmptyDirectory(
923
- new URL(`postbuild/`, jsenvInternalDirectoryUrl),
924
- )
930
+ if (outDirectoryUrl) {
931
+ await ensureEmptyDirectory(new URL(`postbuild/`, outDirectoryUrl))
925
932
  }
926
933
  const finalUrlGraphLoader = createUrlGraphLoader(
927
934
  finalGraphKitchen.kitchenContext,
@@ -1149,7 +1156,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
1149
1156
  const versioningKitchen = createKitchen({
1150
1157
  logLevel: logger.level,
1151
1158
  rootDirectoryUrl: buildDirectoryUrl,
1152
- jsenvInternalDirectoryUrl,
1153
1159
  urlGraph: finalGraph,
1154
1160
  build: true,
1155
1161
  runtimeCompat,
@@ -1265,8 +1271,9 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
1265
1271
  sourcemaps,
1266
1272
  sourcemapsSourcesContent,
1267
1273
  sourcemapsSourcesRelative: true,
1268
- writeGeneratedFiles,
1269
- outDirectoryUrl: new URL("postbuild/", jsenvInternalDirectoryUrl),
1274
+ outDirectoryUrl: outDirectoryUrl
1275
+ ? new URL("postbuild/", outDirectoryUrl)
1276
+ : undefined,
1270
1277
  })
1271
1278
  const versioningUrlGraphLoader = createUrlGraphLoader(
1272
1279
  versioningKitchen.kitchenContext,
@@ -4,7 +4,6 @@ import { bufferToEtag } from "@jsenv/filesystem"
4
4
  import { moveUrl, asUrlWithoutSearch } from "@jsenv/urls"
5
5
  import { URL_META } from "@jsenv/url-meta"
6
6
 
7
- import { determineJsenvInternalDirectoryUrl } from "../jsenv_internal_directory.js"
8
7
  import { watchSourceFiles } from "../watch_source_files.js"
9
8
  import { explorerHtmlFileUrl } from "@jsenv/core/src/plugins/explorer/jsenv_plugin_explorer.js"
10
9
  import { createUrlGraph } from "@jsenv/core/src/kitchen/url_graph.js"
@@ -40,7 +39,7 @@ export const createFileService = ({
40
39
  sourcemaps,
41
40
  sourcemapsSourcesProtocol,
42
41
  sourcemapsSourcesContent,
43
- writeGeneratedFiles,
42
+ outDirectoryUrl,
44
43
  }) => {
45
44
  const clientFileChangeCallbackList = []
46
45
  const clientFilesPruneCallbackList = []
@@ -90,8 +89,6 @@ export const createFileService = ({
90
89
  })
91
90
  })
92
91
  const clientRuntimeCompat = { [runtimeName]: runtimeVersion }
93
- const jsenvInternalDirectoryUrl =
94
- determineJsenvInternalDirectoryUrl(sourceDirectoryUrl)
95
92
 
96
93
  let mainFileUrl
97
94
  if (sourceMainFilePath === undefined) {
@@ -105,7 +102,6 @@ export const createFileService = ({
105
102
  signal,
106
103
  logLevel,
107
104
  rootDirectoryUrl: sourceDirectoryUrl,
108
- jsenvInternalDirectoryUrl,
109
105
  urlGraph,
110
106
  dev: true,
111
107
  runtimeCompat,
@@ -143,11 +139,9 @@ export const createFileService = ({
143
139
  sourcemaps,
144
140
  sourcemapsSourcesProtocol,
145
141
  sourcemapsSourcesContent,
146
- writeGeneratedFiles,
147
- outDirectoryUrl: new URL(
148
- `${runtimeName}@${runtimeVersion}/`,
149
- jsenvInternalDirectoryUrl,
150
- ),
142
+ outDirectoryUrl: outDirectoryUrl
143
+ ? new URL(`${runtimeName}@${runtimeVersion}/`, outDirectoryUrl)
144
+ : undefined,
151
145
  })
152
146
  urlGraph.createUrlInfoCallbackRef.current = (urlInfo) => {
153
147
  const { watch } = URL_META.applyAssociations({
@@ -9,6 +9,7 @@ import {
9
9
  } from "@jsenv/server"
10
10
  import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
11
11
 
12
+ import { lookupPackageDirectory } from "../lookup_package_directory.js"
12
13
  import { createServerEventsDispatcher } from "@jsenv/core/src/plugins/server_events/server_events_dispatcher.js"
13
14
  import { defaultRuntimeCompat } from "@jsenv/core/src/build/build.js"
14
15
  import { createFileService } from "./file_service.js"
@@ -62,9 +63,7 @@ export const startDevServer = async ({
62
63
  sourcemaps = "inline",
63
64
  sourcemapsSourcesProtocol,
64
65
  sourcemapsSourcesContent,
65
- // no real need to write files during github workflow
66
- // and mitigates https://github.com/actions/runner-images/issues/3885
67
- writeGeneratedFiles = !process.env.CI,
66
+ outDirectoryUrl,
68
67
  ...rest
69
68
  }) => {
70
69
  // params type checking
@@ -79,6 +78,17 @@ export const startDevServer = async ({
79
78
  sourceDirectoryUrl,
80
79
  "sourceDirectoryUrl",
81
80
  )
81
+ if (outDirectoryUrl === undefined) {
82
+ const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl)
83
+ if (packageDirectoryUrl) {
84
+ outDirectoryUrl = `${packageDirectoryUrl}.jsenv/`
85
+ }
86
+ } else {
87
+ outDirectoryUrl = assertAndNormalizeDirectoryUrl(
88
+ outDirectoryUrl,
89
+ "outDirectoryUrl",
90
+ )
91
+ }
82
92
  }
83
93
 
84
94
  const logger = createLogger({ logLevel })
@@ -182,7 +192,7 @@ export const startDevServer = async ({
182
192
  sourcemaps,
183
193
  sourcemapsSourcesProtocol,
184
194
  sourcemapsSourcesContent,
185
- writeGeneratedFiles,
195
+ outDirectoryUrl,
186
196
  }),
187
197
  handleWebsocket: (websocket, { request }) => {
188
198
  if (request.headers["sec-websocket-protocol"] === "jsenv") {
@@ -31,6 +31,12 @@ export const createResolveUrlError = ({
31
31
  reason: `no plugin has handled the specifier during "resolveUrl" hook`,
32
32
  })
33
33
  }
34
+ if (error.code === "DIRECTORY_REFERENCE_NOT_ALLOWED") {
35
+ error.message = createDetailedMessage(error.message, {
36
+ "reference trace": reference.trace.message,
37
+ })
38
+ return error
39
+ }
34
40
  return createFailedToResolveUrlError({
35
41
  reason: `An error occured during specifier resolution`,
36
42
  ...detailsFromValueThrown(error),
@@ -114,6 +120,9 @@ export const createTransformUrlContentError = ({
114
120
  urlInfo,
115
121
  error,
116
122
  }) => {
123
+ if (error.code === "DIRECTORY_REFERENCE_NOT_ALLOWED") {
124
+ return error
125
+ }
117
126
  const createFailedToTransformError = ({
118
127
  code = error.code || "TRANSFORM_URL_CONTENT_ERROR",
119
128
  reason,
@@ -28,7 +28,6 @@ export const createKitchen = ({
28
28
  logLevel,
29
29
 
30
30
  rootDirectoryUrl,
31
- jsenvInternalDirectoryUrl,
32
31
  urlGraph,
33
32
  dev = false,
34
33
  build = false,
@@ -43,7 +42,6 @@ export const createKitchen = ({
43
42
  sourcemapsSourcesProtocol,
44
43
  sourcemapsSourcesContent,
45
44
  sourcemapsSourcesRelative,
46
- writeGeneratedFiles,
47
45
  outDirectoryUrl,
48
46
  }) => {
49
47
  const logger = createLogger({ logLevel })
@@ -51,7 +49,6 @@ export const createKitchen = ({
51
49
  signal,
52
50
  logger,
53
51
  rootDirectoryUrl,
54
- jsenvInternalDirectoryUrl,
55
52
  urlGraph,
56
53
  dev,
57
54
  build,
@@ -112,6 +109,7 @@ export const createKitchen = ({
112
109
  assert,
113
110
  assertNode,
114
111
  typePropertyNode,
112
+ leadsToADirectory = false,
115
113
  debug = false,
116
114
  }) => {
117
115
  if (typeof specifier !== "string") {
@@ -165,6 +163,7 @@ export const createKitchen = ({
165
163
  assert,
166
164
  assertNode,
167
165
  typePropertyNode,
166
+ leadsToADirectory,
168
167
  mutation: null,
169
168
  debug,
170
169
  }
@@ -658,7 +657,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
658
657
  )
659
658
  }
660
659
  const cook = memoizeCook(async (urlInfo, context) => {
661
- if (!writeGeneratedFiles || !outDirectoryUrl) {
660
+ if (!outDirectoryUrl) {
662
661
  await _cook(urlInfo, context)
663
662
  return
664
663
  }
@@ -92,18 +92,21 @@ export const createUrlInfoTransformer = ({
92
92
  generatedUrlObject.searchParams.delete("as_js_classic_library")
93
93
  const urlForSourcemap = generatedUrlObject.href
94
94
  urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(urlForSourcemap)
95
- const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder({
96
- urlInfo,
97
- specifier: urlInfo.sourcemapGeneratedUrl,
98
- })
99
- urlInfo.sourcemapReference = sourcemapReference
100
- sourcemapUrlInfo.isInline = sourcemaps === "inline"
101
95
 
102
96
  // already loaded during "load" hook (happens during build)
103
97
  if (urlInfo.sourcemap) {
98
+ const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder(
99
+ {
100
+ urlInfo,
101
+ specifier: urlInfo.sourcemapGeneratedUrl,
102
+ },
103
+ )
104
+ sourcemapUrlInfo.isInline = sourcemaps === "inline"
105
+ urlInfo.sourcemapReference = sourcemapReference
104
106
  urlInfo.sourcemap = normalizeSourcemap(urlInfo, urlInfo.sourcemap)
105
107
  return
106
108
  }
109
+
107
110
  // check for existing sourcemap for this content
108
111
  const sourcemapFound = SOURCEMAP.readComment({
109
112
  contentType: urlInfo.contentType,
@@ -120,6 +123,7 @@ export const createUrlInfoTransformer = ({
120
123
  })
121
124
  try {
122
125
  await context.cook(sourcemapUrlInfo, { reference: sourcemapReference })
126
+ sourcemapUrlInfo.isInline = sourcemaps === "inline"
123
127
  const sourcemapRaw = JSON.parse(sourcemapUrlInfo.content)
124
128
  const sourcemap = normalizeSourcemap(urlInfo, sourcemapRaw)
125
129
  urlInfo.sourcemap = sourcemap
@@ -127,6 +131,12 @@ export const createUrlInfoTransformer = ({
127
131
  logger.error(`Error while handling existing sourcemap: ${e.message}`)
128
132
  return
129
133
  }
134
+ } else {
135
+ const [, sourcemapUrlInfo] = injectSourcemapPlaceholder({
136
+ urlInfo,
137
+ specifier: urlInfo.sourcemapGeneratedUrl,
138
+ })
139
+ sourcemapUrlInfo.isInline = sourcemaps === "inline"
130
140
  }
131
141
  }
132
142
 
@@ -46,54 +46,66 @@ export const jsenvPluginFileUrls = ({
46
46
  const pathnameUsesTrailingSlash = pathname.endsWith("/")
47
47
  urlObject.search = ""
48
48
  urlObject.hash = ""
49
- const foundADirectory = stat && stat.isDirectory()
50
- const foundSomething = stat && !foundADirectory
51
49
  // force trailing slash on directories
52
- if (foundADirectory && !pathnameUsesTrailingSlash) {
50
+ if (stat && stat.isDirectory() && !pathnameUsesTrailingSlash) {
53
51
  urlObject.pathname = `${pathname}/`
54
52
  }
55
53
  // otherwise remove trailing slash if any
56
- if (foundSomething && pathnameUsesTrailingSlash) {
54
+ if (stat && !stat.isDirectory() && pathnameUsesTrailingSlash) {
57
55
  // a warning here? (because it's strange to reference a file with a trailing slash)
58
56
  urlObject.pathname = pathname.slice(0, -1)
59
57
  }
60
- if (foundADirectory && directoryReferenceAllowed) {
61
- if (
62
- // ignore new URL second arg
63
- reference.subtype === "new_url_second_arg" ||
58
+
59
+ let url = urlObject.href
60
+ const shouldPreserve =
61
+ stat &&
62
+ stat.isDirectory() &&
63
+ // ignore new URL second arg
64
+ (reference.subtype === "new_url_second_arg" ||
64
65
  // ignore root file url
65
- reference.url === "file:///"
66
- ) {
67
- reference.shouldHandle = false
66
+ reference.url === "file:///" ||
67
+ (reference.subtype === "new_url_first_arg" &&
68
+ reference.specifier === "./"))
69
+
70
+ if (shouldPreserve) {
71
+ reference.shouldHandle = false
72
+ } else {
73
+ const shouldApplyDilesystemMagicResolution =
74
+ reference.type === "js_import"
75
+ if (shouldApplyDilesystemMagicResolution) {
76
+ const filesystemResolution = applyFileSystemMagicResolution(url, {
77
+ fileStat: stat,
78
+ magicDirectoryIndex,
79
+ magicExtensions: getExtensionsToTry(
80
+ magicExtensions,
81
+ reference.parentUrl,
82
+ ),
83
+ })
84
+ if (filesystemResolution.stat) {
85
+ stat = filesystemResolution.stat
86
+ url = filesystemResolution.url
87
+ }
88
+ }
89
+ if (stat && stat.isDirectory()) {
90
+ const directoryAllowed =
91
+ reference.type === "filesystem" ||
92
+ (typeof directoryReferenceAllowed === "function" &&
93
+ directoryReferenceAllowed(reference)) ||
94
+ directoryReferenceAllowed
95
+ if (!directoryAllowed) {
96
+ const error = new Error("Reference leads to a directory")
97
+ error.code = "DIRECTORY_REFERENCE_NOT_ALLOWED"
98
+ throw error
99
+ }
68
100
  }
69
- reference.data.foundADirectory = true
70
- const directoryFacadeUrl = urlObject.href
71
- const directoryUrlRaw = preserveSymlinks
72
- ? directoryFacadeUrl
73
- : resolveSymlink(directoryFacadeUrl)
74
- const directoryUrl = `${directoryUrlRaw}${search}${hash}`
75
- return directoryUrl
76
101
  }
77
- const url = urlObject.href
78
- const filesystemResolution = applyFileSystemMagicResolution(url, {
79
- fileStat: stat,
80
- magicDirectoryIndex,
81
- magicExtensions: getExtensionsToTry(
82
- magicExtensions,
83
- reference.parentUrl,
84
- ),
85
- })
86
- if (!filesystemResolution.found) {
87
- reference.data.foundADirectory = foundADirectory
88
- return null
102
+ reference.leadsToADirectory = stat && stat.isDirectory()
103
+ if (stat) {
104
+ const urlRaw = preserveSymlinks ? url : resolveSymlink(url)
105
+ const resolvedUrl = `${urlRaw}${search}${hash}`
106
+ return resolvedUrl
89
107
  }
90
- reference.data.foundADirectory = filesystemResolution.isDirectory
91
- const fileFacadeUrl = filesystemResolution.url
92
- const fileUrlRaw = preserveSymlinks
93
- ? fileFacadeUrl
94
- : resolveSymlink(fileFacadeUrl)
95
- const fileUrl = `${fileUrlRaw}${search}${hash}`
96
- return fileUrl
108
+ return null
97
109
  },
98
110
  },
99
111
  {
@@ -145,28 +157,23 @@ export const jsenvPluginFileUrls = ({
145
157
  return null
146
158
  }
147
159
  const urlObject = new URL(urlInfo.url)
148
- if (context.reference.data.foundADirectory) {
149
- if (directoryReferenceAllowed) {
150
- const directoryEntries = readdirSync(urlObject)
151
- let filename
152
- if (context.reference.type === "filesystem") {
153
- const parentUrlInfo = context.urlGraph.getUrlInfo(
154
- context.reference.parentUrl,
155
- )
156
- filename = `${parentUrlInfo.filename}${context.reference.specifier}/`
157
- } else {
158
- filename = `${urlToFilename(urlInfo.url)}/`
159
- }
160
- return {
161
- type: "directory",
162
- contentType: "application/json",
163
- content: JSON.stringify(directoryEntries, null, " "),
164
- filename,
165
- }
160
+ if (context.reference.leadsToADirectory) {
161
+ const directoryEntries = readdirSync(urlObject)
162
+ let filename
163
+ if (context.reference.type === "filesystem") {
164
+ const parentUrlInfo = context.urlGraph.getUrlInfo(
165
+ context.reference.parentUrl,
166
+ )
167
+ filename = `${parentUrlInfo.filename}${context.reference.specifier}/`
168
+ } else {
169
+ filename = `${urlToFilename(urlInfo.url)}/`
170
+ }
171
+ return {
172
+ type: "directory",
173
+ contentType: "application/json",
174
+ content: JSON.stringify(directoryEntries, null, " "),
175
+ filename,
166
176
  }
167
- const error = new Error("found a directory on filesystem")
168
- error.code = "DIRECTORY_REFERENCE_NOT_ALLOWED"
169
- throw error
170
177
  }
171
178
  const fileBuffer = readFileSync(urlObject)
172
179
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url)
@@ -49,7 +49,7 @@ export const jsenvPluginAsJsClassicLibrary = ({
49
49
  jsModuleUrlInfos: [jsModuleUrlInfo],
50
50
  context: {
51
51
  ...context,
52
- buildDirectoryUrl: context.outDirectoryUrl,
52
+ buildDirectoryUrl: new URL("./", import.meta.url),
53
53
  },
54
54
  preserveDynamicImport: true,
55
55
  })
@@ -2,15 +2,6 @@ export const parseAndTransformWebmanifestUrls = async (urlInfo, context) => {
2
2
  const content = urlInfo.content
3
3
  const manifest = JSON.parse(content)
4
4
  const actions = []
5
- const { start_url } = manifest
6
- if (start_url) {
7
- if (context.build) {
8
- manifest.start_url = "/"
9
- } else {
10
- const parentUrl = context.reference.parentUrl
11
- manifest.start_url = `${parentUrl.slice(context.rootDirectoryUrl.length)}`
12
- }
13
- }
14
5
  const { icons = [] } = manifest
15
6
  icons.forEach((icon) => {
16
7
  const [reference] = context.referenceUtils.found({
@@ -149,7 +149,7 @@ export const executeTestPlan = async ({
149
149
  await import(devServerModuleUrl)
150
150
  delete process.env.IMPORTED_BY_TEST_PLAN
151
151
  } catch (e) {
152
- if (e.code === "MODULE_NOT_FOUND") {
152
+ if (e.code === "ERR_MODULE_NOT_FOUND") {
153
153
  throw new Error(
154
154
  `Cannot find file responsible to start dev server at "${devServerModuleUrl}"`,
155
155
  )
@@ -1,18 +0,0 @@
1
- import { basename } from "node:path"
2
-
3
- import { lookupPackageDirectory } from "./lookup_package_directory.js"
4
-
5
- export const determineJsenvInternalDirectoryUrl = (currentUrl) => {
6
- const packageDirectoryUrl = lookupPackageDirectory(currentUrl)
7
- if (packageDirectoryUrl) {
8
- return `${packageDirectoryUrl}.jsenv/${getDirectoryName(
9
- packageDirectoryUrl,
10
- )}/`
11
- }
12
- return `${currentUrl}.jsenv/`
13
- }
14
-
15
- const getDirectoryName = (directoryUrl) => {
16
- const { pathname } = new URL(directoryUrl)
17
- return basename(pathname)
18
- }