@jsenv/core 35.0.5 → 36.0.1

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 (50) hide show
  1. package/README.md +1 -1
  2. package/dist/js/inline_content.js +5 -4
  3. package/dist/jsenv_core.js +1127 -1497
  4. package/package.json +8 -8
  5. package/src/build/build.js +49 -41
  6. package/src/dev/file_service.js +7 -17
  7. package/src/dev/start_dev_server.js +12 -7
  8. package/src/kitchen/kitchen.js +38 -19
  9. package/src/kitchen/url_graph.js +1 -1
  10. package/src/plugins/autoreload/jsenv_plugin_hmr.js +2 -2
  11. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -4
  12. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +1 -1
  13. package/src/plugins/importmap/jsenv_plugin_importmap.js +1 -1
  14. package/src/plugins/inlining/jsenv_plugin_inlining.js +1 -1
  15. package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +13 -2
  16. package/src/plugins/plugin_controller.js +19 -10
  17. package/src/plugins/plugins.js +21 -25
  18. package/src/plugins/{url_analysis/css/css_urls.js → reference_analysis/css/jsenv_plugin_css_reference_analysis.js} +11 -1
  19. package/src/plugins/{inline_content_analysis/jsenv_plugin_data_urls.js → reference_analysis/data_urls/jsenv_plugin_data_urls_analysis.js} +19 -19
  20. package/src/plugins/reference_analysis/directory/jsenv_plugin_directory_reference_analysis.js +51 -0
  21. package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +429 -0
  22. package/src/plugins/reference_analysis/inline_content.js +7 -0
  23. package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +161 -0
  24. package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +120 -0
  25. package/src/plugins/{url_analysis → reference_analysis}/jsenv_plugin_reference_expected_types.js +19 -12
  26. package/src/plugins/{url_analysis/webmanifest/webmanifest_urls.js → reference_analysis/webmanifest/jsenv_plugin_webmanifest_reference_analysis.js} +13 -1
  27. package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +74 -0
  28. package/src/plugins/{url_resolution → resolution_node_esm}/node_esm_resolver.js +8 -0
  29. package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +45 -0
  30. package/src/plugins/transpilation/as_js_module/jsenv_plugin_as_js_module.js +1 -1
  31. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
  32. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +4 -6
  33. package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_conversion.js +1 -1
  34. package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +4 -6
  35. package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +1 -1
  36. package/src/plugins/url_type_from_reference.js +13 -0
  37. package/src/plugins/{url_version/jsenv_plugin_url_version.js → version_search_param/jsenv_plugin_version_search_param.js} +4 -4
  38. package/dist/html/explorer.html +0 -559
  39. package/dist/other/jsenv.png +0 -0
  40. package/src/plugins/explorer/client/explorer.html +0 -608
  41. package/src/plugins/explorer/client/jsenv.png +0 -0
  42. package/src/plugins/explorer/jsenv_plugin_explorer.js +0 -86
  43. package/src/plugins/inline_content_analysis/client/inline_content.js +0 -6
  44. package/src/plugins/inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js +0 -206
  45. package/src/plugins/inline_content_analysis/jsenv_plugin_inline_content_analysis.js +0 -34
  46. package/src/plugins/inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js +0 -314
  47. package/src/plugins/url_analysis/html/html_urls.js +0 -313
  48. package/src/plugins/url_analysis/js/js_urls.js +0 -65
  49. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +0 -116
  50. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +0 -140
@@ -1,608 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Exploring</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <meta charset="utf-8" />
7
- <link rel="icon" href="ignore:FAVICON_HREF" />
8
- <style>
9
- button:focus,
10
- a:focus,
11
- input:focus,
12
- *[data-contains-hidden-input] input:focus + * {
13
- outline-style: none;
14
- outline-offset: -2px;
15
- }
16
-
17
- *[data-contains-hidden-input] input:focus + * {
18
- outline-width: 4px;
19
- outline-offset: -2px;
20
- }
21
-
22
- html[data-last-interaction="keyboard"] button:focus,
23
- html[data-last-interaction="keyboard"] a:focus,
24
- html[data-last-interaction="keyboard"] input:focus,
25
- html[data-last-interaction="keyboard"]
26
- *[data-contains-hidden-input]
27
- input:focus
28
- + * {
29
- outline-style: auto;
30
- }
31
-
32
- html[data-last-interaction="keyboard"]
33
- *[data-contains-hidden-input]
34
- input:focus
35
- + * {
36
- outline-color: rgb(0, 150, 255);
37
- }
38
-
39
- /*
40
- Don't try to replace @-moz-document url-prefix() this by
41
- -moz-outline or -moz-outline-color
42
- Because firefox would take into account outline instead of -moz-outline
43
- :moz-focus-ring
44
- Because for some element we set the focus outline on a div which would not match :focusring
45
- */
46
- @-moz-document url-prefix() {
47
- html[data-last-interaction="keyboard"] button:focus,
48
- html[data-last-interaction="keyboard"] a:focus,
49
- html[data-last-interaction="keyboard"] input:focus,
50
- html[data-last-interaction="keyboard"]
51
- *[data-input-customized]
52
- input:focus
53
- + * {
54
- outline-width: 2px;
55
- outline-offset: 0;
56
- outline-style: solid;
57
- /*
58
- force a blue color for firefox otherwise
59
- it uses outline-color: inherit
60
- making it unpredictible and sometimes hard to see
61
- */
62
- outline-color: rgb(0, 150, 255);
63
- }
64
- }
65
- ::-moz-focus-inner {
66
- border: 0;
67
- }
68
- </style>
69
- <style>
70
- /* reset stuff */
71
- * {
72
- box-sizing: border-box;
73
- }
74
-
75
- [data-force-hide] {
76
- display: none !important;
77
- }
78
-
79
- html,
80
- body {
81
- margin: 0;
82
- padding: 0;
83
- display: flex;
84
- flex-direction: column;
85
- flex: 1;
86
- }
87
-
88
- html {
89
- font-family: arial, sans;
90
- height: 100%;
91
- }
92
-
93
- main {
94
- display: flex;
95
- flex-direction: column;
96
- flex: 1;
97
- }
98
-
99
- main > * {
100
- min-width: 100%;
101
- flex: 1;
102
- }
103
-
104
- hr {
105
- color: black;
106
- background-color: black;
107
- border-color: black;
108
- margin: 15px 0;
109
- }
110
-
111
- article[data-page="file-list"] {
112
- background-color: #204143;
113
- color: #97a0a0;
114
- }
115
-
116
- nav,
117
- #explorables-message {
118
- background: #1f262c;
119
- }
120
-
121
- #explorables nav {
122
- /* overflow hidden to ensure it wraps li which have margins
123
- otherwise the background color is not the one from <nav> */
124
- overflow: hidden;
125
- }
126
-
127
- #explorables-message {
128
- overflow: auto; /* propagate background to margins cause by h4 inside */
129
- }
130
-
131
- article h2 {
132
- margin: 0;
133
- display: flex;
134
- }
135
-
136
- article h2 svg {
137
- margin-right: 15px;
138
- }
139
-
140
- #main_html_file {
141
- padding: 25px;
142
- padding-bottom: 0;
143
- }
144
-
145
- #main_file_link {
146
- color: #e7f2f3;
147
- }
148
-
149
- h2 {
150
- margin: 20px 0;
151
- color: #24b1b0;
152
- display: inline-block;
153
- }
154
-
155
- h4 {
156
- font-weight: normal;
157
- font-size: 15px;
158
- color: #97a0a0;
159
- padding: 0 25px;
160
- }
161
-
162
- #explorables {
163
- word-break: break-word;
164
- }
165
-
166
- #explorables-header {
167
- /* padding-bottom: 10px; */
168
- width: 100%;
169
- position: sticky;
170
- top: 0;
171
- }
172
-
173
- #explorables_header_and_menu {
174
- padding-left: 25px;
175
- padding-right: 25px;
176
- padding-top: 25px;
177
- background-color: #204143;
178
- position: relative;
179
- }
180
-
181
- #explorables_header_bottom_spacing {
182
- height: 20px;
183
- background: #1f262c;
184
- }
185
-
186
- #directory_relative_url {
187
- color: orange;
188
- }
189
-
190
- #explorables ul {
191
- padding: 0px 25px 25px 25px;
192
- margin: 0;
193
- }
194
-
195
- #explorables li {
196
- list-style-type: none;
197
- margin: 10px 0;
198
- }
199
-
200
- #explorables li:first-child {
201
- margin-top: 0;
202
- }
203
-
204
- #explorables li .execution-link {
205
- width: 100%;
206
- word-break: break-all;
207
- }
208
-
209
- .execution-link {
210
- background: #204143;
211
- padding: 6px 12px;
212
- font-size: 14px;
213
- display: inline-block;
214
- color: #e7f2f3;
215
- font-family: monospace;
216
- text-decoration: unset;
217
- }
218
-
219
- /* icons */
220
- #main_file_icon {
221
- fill: #24b1b0;
222
- }
223
-
224
- #explorables_icon {
225
- width: 25px;
226
- height: 25px;
227
- stroke: none;
228
- fill: #24b1b0;
229
- }
230
-
231
- #explorables fieldset {
232
- border: none;
233
- padding: 0;
234
- margin: 0;
235
- }
236
-
237
- #explorables fieldset label {
238
- display: inline-block;
239
- padding: 0;
240
- }
241
-
242
- #explorables fieldset input {
243
- opacity: 0;
244
- position: absolute;
245
- }
246
-
247
- #explorables fieldset label input + * {
248
- display: block;
249
- padding: 0.7em 1em;
250
- background-color: #204143;
251
- border-radius: 0.1em;
252
- min-width: 8em;
253
- text-align: center;
254
- }
255
-
256
- #explorables fieldset input:checked + * {
257
- color: orange;
258
- background: #1f262c;
259
- }
260
-
261
- /* scrolable menu */
262
- .menu-wrapper {
263
- position: relative;
264
- max-width: 100%;
265
- overflow-x: hidden;
266
- overflow-y: hidden;
267
- transition: 300ms;
268
- margin-top: 25px;
269
- }
270
- .menu {
271
- box-sizing: border-box;
272
- white-space: nowrap;
273
- overflow-x: auto;
274
- overflow-y: hidden;
275
- -webkit-overflow-scrolling: touch;
276
- }
277
- .menu .item {
278
- display: inline-block;
279
- height: 100%;
280
- padding: 1em;
281
- box-sizing: border-box;
282
- }
283
- .paddle {
284
- position: absolute;
285
- height: 36px;
286
- bottom: 0;
287
- border: none;
288
- background: #24b1b0;
289
- color: #1f262c;
290
- }
291
- .left-paddle {
292
- left: 0;
293
- }
294
- .right-paddle {
295
- right: 0;
296
- }
297
- .hidden {
298
- display: none;
299
- }
300
- </style>
301
- </head>
302
-
303
- <body>
304
- <main></main>
305
- <div style="display: none">
306
- <article data-page="file-list">
307
- <!--
308
- <section id="main_html_file">
309
- <h2>
310
- <svg id="main_file_icon" viewBox="0 0 16 16" width="25px" height="25px">
311
- <path
312
- d="M15.45,7L14,5.551V2c0-0.55-0.45-1-1-1h-1c-0.55,0-1,0.45-1,1v0.553L9,0.555C8.727,0.297,8.477,0,8,0S7.273,0.297,7,0.555 L0.55,7C0.238,7.325,0,7.562,0,8c0,0.563,0.432,1,1,1h1v6c0,0.55,0.45,1,1,1h3v-5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v5h3 c0.55,0,1-0.45,1-1V9h1c0.568,0,1-0.437,1-1C16,7.562,15.762,7.325,15.45,7z"
313
- />
314
- </svg>
315
- <span
316
- >Main html file:
317
- <a id="main_file_link" href="javascript:void(0)">${mainFileRelativeUrl}</a></span
318
- >
319
- </h2>
320
- <div>
321
- <iframe id="main_file_iframe" src="about:blank"></iframe>
322
- </div>
323
- </section>
324
- <hr />
325
- !-->
326
- <section id="explorables">
327
- <div id="explorables-header">
328
- <div id="explorables_header_and_menu">
329
- <h2>
330
- <svg
331
- id="explorables_icon"
332
- viewBox="0 0 24 24"
333
- width="32"
334
- height="32"
335
- >
336
- <path d="M0 0h24v24H0V0z" fill="none" />
337
- <path
338
- d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"
339
- />
340
- </svg>
341
- <span
342
- >File(s) to explore in
343
- <span id="directory_relative_url" title="${directoryUrl}"
344
- >${directoryName}</span
345
- ></span
346
- >
347
- </h2>
348
- <div class="menu-wrapper">
349
- <fieldset id="filter-group-set" class="menu"></fieldset>
350
- </div>
351
- <div class="paddles">
352
- <button class="left-paddle paddle hidden">&#60;</button>
353
- <button class="right-paddle paddle">&#62;</button>
354
- </div>
355
- </div>
356
- <div id="explorables_header_bottom_spacing"></div>
357
- </div>
358
- <div>
359
- <div id="explorables-message">
360
- <h4 style="margin-top: 0">${message}</h4>
361
- </div>
362
- <nav>
363
- <ul></ul>
364
- </nav>
365
- </div>
366
- </section>
367
- </article>
368
- </div>
369
- <script no-supervisor>
370
- // eslint-disable-next-line no-undef
371
- const { rootDirectoryUrl, groups, files } = SERVER_PARAMS;
372
-
373
- const groupPreference = {
374
- has: () => localStorage.hasOwnProperty("explorer_active_group"),
375
- get: () =>
376
- localStorage.hasOwnProperty("explorer_active_group")
377
- ? JSON.parse(localStorage.getItem("explorer_active_group"))
378
- : undefined,
379
- set: (value) =>
380
- localStorage.setItem("explorer_active_group", JSON.stringify(value)),
381
- };
382
- const directoryNameFromUrl = (directoryUrl) => {
383
- const slashLastIndex = directoryUrl.lastIndexOf(
384
- "/",
385
- // ignore last slash
386
- directoryUrl.length - 2,
387
- );
388
- if (slashLastIndex === -1) return "";
389
- return directoryUrl.slice(slashLastIndex + 1);
390
- };
391
- const urlToVisitFromRelativeUrl = (relativeUrl) => {
392
- return `${window.origin}/${relativeUrl}`;
393
- };
394
-
395
- const fileListElement = document
396
- .querySelector(`[data-page="file-list"]`)
397
- .cloneNode(true);
398
- const directoryName = directoryNameFromUrl(rootDirectoryUrl);
399
- const span = fileListElement.querySelector("#directory_relative_url");
400
- span.title = rootDirectoryUrl;
401
- span.textContent = directoryName;
402
-
403
- const h4 = fileListElement.querySelector("h4");
404
- const ul = fileListElement.querySelector("ul");
405
- ul.innerHTML = files
406
- .map(
407
- (file) =>
408
- `<li>
409
- <a
410
- class="execution-link"
411
- data-relative-url=${file.relativeUrl}
412
- href=${urlToVisitFromRelativeUrl(file.relativeUrl)}
413
- >
414
- ${file.relativeUrl}
415
- </a>
416
- </li>`,
417
- )
418
- .join("");
419
-
420
- const groupFieldset = fileListElement.querySelector("#filter-group-set");
421
- const groupNames = Object.keys(groups);
422
- groupFieldset.innerHTML = groupNames
423
- .map(
424
- (key) => `<label data-contains-hidden-input class="item">
425
- <input type="radio" name="filter-group" value="${key}"/>
426
- <span>${key}</span>
427
- </label>`,
428
- )
429
- .join("");
430
-
431
- const groupFromLocalStorage = groupPreference.get();
432
- const currentGroup =
433
- groupFromLocalStorage && groupNames.includes(groupFromLocalStorage)
434
- ? groupFromLocalStorage
435
- : groupNames[0];
436
- Array.from(groupFieldset.querySelectorAll("input")).forEach(
437
- (inputRadio) => {
438
- inputRadio.checked = inputRadio.value === currentGroup;
439
- inputRadio.onchange = () => {
440
- if (inputRadio.checked) {
441
- groupPreference.set(inputRadio.value);
442
- enableGroup(inputRadio.value);
443
- }
444
- };
445
- },
446
- );
447
-
448
- const enableGroup = (groupName) => {
449
- const arrayOfElementToShow = [];
450
- const arrayOfElementToHide = [];
451
- files.forEach((file) => {
452
- const fileLink = fileListElement.querySelector(
453
- `a[data-relative-url="${file.relativeUrl}"]`,
454
- );
455
- const fileLi = fileLink.parentNode;
456
- if (file.meta[groupName]) {
457
- arrayOfElementToShow.push(fileLi);
458
- } else {
459
- arrayOfElementToHide.push(fileLi);
460
- }
461
- });
462
- arrayOfElementToShow.forEach((element) => {
463
- element.removeAttribute("data-force-hide");
464
- });
465
- arrayOfElementToHide.forEach((element) => {
466
- element.setAttribute("data-force-hide", "");
467
- });
468
-
469
- h4.innerHTML =
470
- arrayOfElementToShow.length === 0
471
- ? `No file found.
472
- Config for this section: <pre>${JSON.stringify(
473
- groups[groupName],
474
- null,
475
- " ",
476
- )}</pre>`
477
- : `${arrayOfElementToShow.length} files found. Click on the one you want to execute`;
478
- };
479
- enableGroup(currentGroup);
480
-
481
- document.querySelector("main").appendChild(fileListElement);
482
- </script>
483
- <script no-supervisor>
484
- // make menu scrollable
485
- const getMenuWrapperSize = () => {
486
- return document.querySelector(".menu-wrapper").getBoundingClientRect()
487
- .width;
488
- };
489
- const getMenuSize = () => {
490
- return document.querySelector(".menu").getBoundingClientRect().width;
491
- };
492
- const getMenuPosition = () => {
493
- return document.querySelector(".menu-wrapper").scrollLeft;
494
- };
495
-
496
- let menuWrapperSize = getMenuWrapperSize();
497
- let menuSize = getMenuSize();
498
- const menuVisibleSize = menuWrapperSize;
499
- let menuInvisibleSize = menuSize - menuVisibleSize;
500
- const scrollDuration = 300;
501
- const leftPaddle = document.querySelector(".left-paddle");
502
- const rightPaddle = document.querySelector(".right-paddle");
503
-
504
- const handleMenuScroll = () => {
505
- menuInvisibleSize = menuSize - menuWrapperSize;
506
- const menuPosition = getMenuPosition();
507
- const menuEndOffset = menuInvisibleSize;
508
- // show & hide the paddles, depending on scroll position
509
- if (menuPosition <= 0 && menuEndOffset <= 0) {
510
- // hide both paddles if the window is large enough to display all tabs
511
- leftPaddle.classList.add("hidden");
512
- rightPaddle.classList.add("hidden");
513
- } else if (menuPosition <= 0) {
514
- leftPaddle.classList.add("hidden");
515
- rightPaddle.classList.remove("hidden");
516
- } else if (menuPosition < Math.floor(menuEndOffset)) {
517
- // show both paddles in the middle
518
- leftPaddle.classList.remove("hidden");
519
- rightPaddle.classList.remove("hidden");
520
- } else if (menuPosition >= Math.floor(menuEndOffset)) {
521
- leftPaddle.classList.remove("hidden");
522
- rightPaddle.classList.add("hidden");
523
- }
524
- };
525
- handleMenuScroll();
526
-
527
- window.onresize = () => {
528
- menuWrapperSize = getMenuWrapperSize();
529
- menuSize = getMenuSize();
530
- handleMenuScroll();
531
- };
532
- // finally, what happens when we are actually scrolling the menu
533
- document.querySelector(".menu-wrapper").onscroll = () => {
534
- handleMenuScroll();
535
- };
536
-
537
- const startJavaScriptAnimation = ({
538
- duration = 300,
539
- timingFunction = (t) => t,
540
- onProgress = () => {},
541
- onCancel = () => {},
542
- onComplete = () => {},
543
- }) => {
544
- duration = parseInt(duration, 10);
545
- const startMs = performance.now();
546
- let currentRequestAnimationFrameId;
547
- let done = false;
548
- let rawProgress = 0;
549
- let progress = 0;
550
- const handler = () => {
551
- currentRequestAnimationFrameId = null;
552
- const nowMs = performance.now();
553
- rawProgress = Math.min((nowMs - startMs) / duration, 1);
554
- progress = timingFunction(rawProgress);
555
- done = rawProgress === 1;
556
- onProgress({
557
- done,
558
- rawProgress,
559
- progress,
560
- });
561
- if (done) {
562
- onComplete();
563
- } else {
564
- currentRequestAnimationFrameId =
565
- window.requestAnimationFrame(handler);
566
- }
567
- };
568
- handler();
569
- const stop = () => {
570
- if (currentRequestAnimationFrameId) {
571
- window.cancelAnimationFrame(currentRequestAnimationFrameId);
572
- currentRequestAnimationFrameId = null;
573
- }
574
- if (!done) {
575
- done = true;
576
- onCancel({
577
- rawProgress,
578
- progress,
579
- });
580
- }
581
- };
582
- return stop;
583
- };
584
- rightPaddle.onclick = () => {
585
- const scrollStart = document.querySelector(".menu-wrapper").scrollLeft;
586
- const scrollEnd = scrollStart + menuWrapperSize;
587
- startJavaScriptAnimation({
588
- duration: scrollDuration,
589
- onProgress: ({ progress }) => {
590
- document.querySelector(".menu-wrapper").scrollLeft =
591
- scrollStart + (scrollEnd - scrollStart) * progress;
592
- },
593
- });
594
- };
595
- leftPaddle.onclick = () => {
596
- const scrollStart = document.querySelector(".menu-wrapper").scrollLeft;
597
- const scrollEnd = scrollStart - menuWrapperSize;
598
- startJavaScriptAnimation({
599
- duration: scrollDuration,
600
- onProgress: ({ progress }) => {
601
- document.querySelector(".menu-wrapper").scrollLeft =
602
- scrollStart + (scrollEnd - scrollStart) * progress;
603
- },
604
- });
605
- };
606
- </script>
607
- </body>
608
- </html>
@@ -1,86 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { DATA_URL } from "@jsenv/urls";
3
- import { collectFiles } from "@jsenv/filesystem";
4
- import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
5
-
6
- export const explorerHtmlFileUrl = String(
7
- new URL("./client/explorer.html", import.meta.url),
8
- );
9
-
10
- export const jsenvPluginExplorer = ({
11
- groups = {
12
- src: {
13
- "./**/*.html": true,
14
- "./**/*.test.html": false,
15
- },
16
- tests: {
17
- "./**/*.test.html": true,
18
- },
19
- },
20
- }) => {
21
- const faviconClientFileUrl = new URL("./client/jsenv.png", import.meta.url);
22
-
23
- return {
24
- name: "jsenv:explorer",
25
- appliesDuring: "dev",
26
- transformUrlContent: {
27
- html: async (urlInfo, context) => {
28
- if (urlInfo.url !== explorerHtmlFileUrl) {
29
- return null;
30
- }
31
- let html = urlInfo.content;
32
- if (html.includes("ignore:FAVICON_HREF")) {
33
- html = html.replace(
34
- "ignore:FAVICON_HREF",
35
- DATA_URL.stringify({
36
- contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
37
- base64Flag: true,
38
- data: readFileSync(new URL(faviconClientFileUrl)).toString(
39
- "base64",
40
- ),
41
- }),
42
- );
43
- }
44
- if (html.includes("SERVER_PARAMS")) {
45
- const associationsForExplorable = {};
46
- Object.keys(groups).forEach((groupName) => {
47
- const groupConfig = groups[groupName];
48
- associationsForExplorable[groupName] = {
49
- "**/.jsenv/": false, // avoid visting .jsenv directory in jsenv itself
50
- ...groupConfig,
51
- };
52
- });
53
- const matchingFileResultArray = await collectFiles({
54
- directoryUrl: context.rootDirectoryUrl,
55
- associations: associationsForExplorable,
56
- predicate: (meta) =>
57
- Object.keys(meta).some((group) => Boolean(meta[group])),
58
- });
59
- const files = matchingFileResultArray.map(
60
- ({ relativeUrl, meta }) => ({
61
- relativeUrl,
62
- meta,
63
- }),
64
- );
65
-
66
- html = html.replace(
67
- "SERVER_PARAMS",
68
- JSON.stringify(
69
- {
70
- rootDirectoryUrl: context.rootDirectoryUrl,
71
- groups,
72
- files,
73
- },
74
- null,
75
- " ",
76
- ),
77
- );
78
- Object.assign(urlInfo.headers, {
79
- "cache-control": "no-store",
80
- });
81
- }
82
- return html;
83
- },
84
- },
85
- };
86
- };
@@ -1,6 +0,0 @@
1
- function InlineContent(content, { type = "text/plain" }) {
2
- this.text = content;
3
- this.type = type;
4
- }
5
-
6
- export { InlineContent };