@jsenv/plugin-supervisor 1.6.5 → 1.6.7

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.
@@ -1013,7 +1013,7 @@ window.__supervisor__ = (() => {
1013
1013
  try {
1014
1014
  if (exception.code === DYNAMIC_IMPORT_FETCH_ERROR || exception.reportedBy === "script_error_event") {
1015
1015
  const errorCauseFile = exception.site.ownerSite ? exception.site.ownerSite.url : exception.site.url;
1016
- const errorCauseAPIUrl = "/__get_error_cause__/".concat(encodeURIComponent(errorCauseFile));
1016
+ const errorCauseAPIUrl = "/.internal/get_error_cause/".concat(encodeURIComponent(errorCauseFile));
1017
1017
  const response = await window.fetch(errorCauseAPIUrl);
1018
1018
  if (response.status !== 200) {
1019
1019
  return;
@@ -1032,7 +1032,7 @@ window.__supervisor__ = (() => {
1032
1032
  line: exception.site.ownerSite.inlineLine,
1033
1033
  column: exception.site.ownerSite.inlineColumn
1034
1034
  }) : stringifyUrlSite(exception.site);
1035
- const errorTraceAPIUrl = "/__get_cause_trace__/".concat(encodeURIComponent(errorTraceFile));
1035
+ const errorTraceAPIUrl = "/.internal/get_cause_trace/".concat(encodeURIComponent(errorTraceFile));
1036
1036
  const urlToFetch = new URL(errorTraceAPIUrl, window.origin);
1037
1037
  if (!exception.stackSourcemapped) {
1038
1038
  urlToFetch.searchParams.set("remap", "");
@@ -1077,7 +1077,7 @@ window.__supervisor__ = (() => {
1077
1077
  }
1078
1078
  const urlWithLineAndColumn = stringifyUrlSite(urlSite);
1079
1079
  return {
1080
- href: urlSite.url.startsWith("file:") && openInEditor ? "javascript:window.fetch('/__open_in_editor__/".concat(encodeURIComponent(urlWithLineAndColumn), "')") : urlSite.url,
1080
+ href: urlSite.url.startsWith("file:") && openInEditor ? "javascript:window.fetch('/.internal/open_file/".concat(encodeURIComponent(urlWithLineAndColumn), "')") : urlSite.url,
1081
1081
  text: urlWithLineAndColumn
1082
1082
  };
1083
1083
  }
@@ -0,0 +1,8 @@
1
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
2
+ const intToChar = new Uint8Array(64); // 64 possible chars.
3
+ const charToInt = new Uint8Array(128); // z is 122 in ASCII
4
+ for (let i = 0; i < chars.length; i++) {
5
+ const c = chars.charCodeAt(i);
6
+ intToChar[i] = c;
7
+ charToInt[c] = i;
8
+ }
@@ -4,6 +4,7 @@ import os from "node:os";
4
4
  import tty from "node:tty";
5
5
  import "string-width";
6
6
  import { pathToFileURL, fileURLToPath } from "node:url";
7
+ import "./js/vendors.js";
7
8
  import { createRequire } from "node:module";
8
9
  import { existsSync, readFileSync, realpathSync } from "node:fs";
9
10
  import "node:path";
@@ -156,6 +157,48 @@ function createSupportsColor(stream, options = {}) {
156
157
  isTTY: tty.isatty(2)
157
158
  })
158
159
  });
160
+ function isUnicodeSupported() {
161
+ const {
162
+ env
163
+ } = process$1;
164
+ const {
165
+ TERM,
166
+ TERM_PROGRAM
167
+ } = env;
168
+ if (process$1.platform !== 'win32') {
169
+ return TERM !== 'linux'; // Linux console (kernel)
170
+ }
171
+ return Boolean(env.WT_SESSION) // Windows Terminal
172
+ || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
173
+ || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
174
+ || TERM_PROGRAM === 'Terminus-Sublime' || TERM_PROGRAM === 'vscode' || TERM === 'xterm-256color' || TERM === 'alacritty' || TERM === 'rxvt-unicode' || TERM === 'rxvt-unicode-256color' || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
175
+ }
176
+
177
+ /* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
178
+
179
+ const isBrowser = globalThis.window?.document !== undefined;
180
+ globalThis.process?.versions?.node !== undefined;
181
+ globalThis.process?.versions?.bun !== undefined;
182
+ globalThis.Deno?.version?.deno !== undefined;
183
+ globalThis.process?.versions?.electron !== undefined;
184
+ globalThis.navigator?.userAgent?.includes('jsdom') === true;
185
+ typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
186
+ typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
187
+ typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
188
+ typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
189
+
190
+ // Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
191
+ const platform = globalThis.navigator?.userAgentData?.platform;
192
+ platform === 'macOS' || globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
193
+ || globalThis.navigator?.userAgent?.includes(' Mac ') === true || globalThis.process?.platform === 'darwin';
194
+ platform === 'Windows' || globalThis.navigator?.platform === 'Win32' || globalThis.process?.platform === 'win32';
195
+ platform === 'Linux' || globalThis.navigator?.platform?.startsWith('Linux') === true || globalThis.navigator?.userAgent?.includes(' Linux ') === true || globalThis.process?.platform === 'linux';
196
+ platform === 'Android' || globalThis.navigator?.platform === 'Android' || globalThis.navigator?.userAgent?.includes(' Android ') === true || globalThis.process?.platform === 'android';
197
+ !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
198
+ !isBrowser && process$1.platform === 'win32';
199
+ isBrowser ? () => {
200
+ throw new Error('`process.cwd()` only works in Node.js, not the browser.');
201
+ } : process$1.cwd;
159
202
 
160
203
  // https://github.com/Marak/colors.js/blob/master/lib/styles.js
161
204
  // https://stackoverflow.com/a/75985833/2634179
@@ -211,22 +254,6 @@ const ANSI = createAnsi({
211
254
  // because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
212
255
  process.env.GITHUB_WORKFLOW
213
256
  });
214
- function isUnicodeSupported() {
215
- const {
216
- env
217
- } = process$1;
218
- const {
219
- TERM,
220
- TERM_PROGRAM
221
- } = env;
222
- if (process$1.platform !== 'win32') {
223
- return TERM !== 'linux'; // Linux console (kernel)
224
- }
225
- return Boolean(env.WT_SESSION) // Windows Terminal
226
- || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
227
- || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
228
- || TERM_PROGRAM === 'Terminus-Sublime' || TERM_PROGRAM === 'vscode' || TERM === 'xterm-256color' || TERM === 'alacritty' || TERM === 'rxvt-unicode' || TERM === 'rxvt-unicode-256color' || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
229
- }
230
257
 
231
258
  // see also https://github.com/sindresorhus/figures
232
259
 
@@ -439,32 +466,6 @@ const fillLeft = (value, biggestValue, char = " ") => {
439
466
  return padded;
440
467
  };
441
468
 
442
- /* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
443
-
444
- const isBrowser = globalThis.window?.document !== undefined;
445
- globalThis.process?.versions?.node !== undefined;
446
- globalThis.process?.versions?.bun !== undefined;
447
- globalThis.Deno?.version?.deno !== undefined;
448
- globalThis.process?.versions?.electron !== undefined;
449
- globalThis.navigator?.userAgent?.includes('jsdom') === true;
450
- typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
451
- typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
452
- typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
453
- typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
454
-
455
- // Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
456
- const platform = globalThis.navigator?.userAgentData?.platform;
457
- platform === 'macOS' || globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
458
- || globalThis.navigator?.userAgent?.includes(' Mac ') === true || globalThis.process?.platform === 'darwin';
459
- platform === 'Windows' || globalThis.navigator?.platform === 'Win32' || globalThis.process?.platform === 'win32';
460
- platform === 'Linux' || globalThis.navigator?.platform?.startsWith('Linux') === true || globalThis.navigator?.userAgent?.includes(' Linux ') === true || globalThis.process?.platform === 'linux';
461
- platform === 'Android' || globalThis.navigator?.platform === 'Android' || globalThis.navigator?.userAgent?.includes(' Android ') === true || globalThis.process?.platform === 'android';
462
- !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
463
- !isBrowser && process$1.platform === 'win32';
464
- isBrowser ? () => {
465
- throw new Error('`process.cwd()` only works in Node.js, not the browser.');
466
- } : process$1.cwd;
467
-
468
469
  // normalize url search params:
469
470
  // Using URLSearchParams to alter the url search params
470
471
  // can result into "file:///file.css?css_module"
@@ -605,41 +606,6 @@ const pathnameToParentPathname = pathname => {
605
606
  return pathname.slice(0, slashLastIndex + 1);
606
607
  };
607
608
 
608
- const urlToFileSystemPath = url => {
609
- const urlObject = new URL(url);
610
- let {
611
- origin,
612
- pathname,
613
- hash
614
- } = urlObject;
615
- if (urlObject.protocol === "file:") {
616
- origin = "file://";
617
- }
618
- pathname = pathname.split("/").map(part => {
619
- return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
620
- }).join("/");
621
- if (hash) {
622
- pathname += "%23".concat(encodeURIComponent(hash.slice(1)));
623
- }
624
- const urlString = "".concat(origin).concat(pathname);
625
- const fileSystemPath = fileURLToPath(urlString);
626
- if (fileSystemPath[fileSystemPath.length - 1] === "/") {
627
- // remove trailing / so that nodejs path becomes predictable otherwise it logs
628
- // the trailing slash on linux but does not on windows
629
- return fileSystemPath.slice(0, -1);
630
- }
631
- return fileSystemPath;
632
- };
633
-
634
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
635
- const intToChar = new Uint8Array(64); // 64 possible chars.
636
- const charToInt = new Uint8Array(128); // z is 122 in ASCII
637
- for (let i = 0; i < chars.length; i++) {
638
- const c = chars.charCodeAt(i);
639
- intToChar[i] = c;
640
- charToInt[c] = i;
641
- }
642
-
643
609
  const require = createRequire(import.meta.url);
644
610
  // consider using https://github.com/7rulnik/source-map-js
645
611
 
@@ -1227,7 +1193,7 @@ const injectSupervisorIntoHTML = async ({
1227
1193
  }
1228
1194
  const src = getHtmlNodeAttribute(scriptNode, "src");
1229
1195
  if (src) {
1230
- const urlObject = new URL(src, "http://example.com/");
1196
+ const urlObject = new URL(src, "http://example.com");
1231
1197
  if (urlObject.searchParams.has("inline")) {
1232
1198
  return;
1233
1199
  }
@@ -1280,7 +1246,7 @@ const generateCodeToSuperviseScriptWithSrc = ({
1280
1246
  // https://nodejs.org/api/packages.html#resolving-user-conditions
1281
1247
  const readCustomConditionsFromProcessArgs = () => {
1282
1248
  const packageConditions = [];
1283
- process.execArgv.forEach(arg => {
1249
+ for (const arg of process.execArgv) {
1284
1250
  if (arg.includes("-C=")) {
1285
1251
  const packageCondition = arg.slice(0, "-C=".length);
1286
1252
  packageConditions.push(packageCondition);
@@ -1289,7 +1255,7 @@ const readCustomConditionsFromProcessArgs = () => {
1289
1255
  const packageCondition = arg.slice("--conditions=".length);
1290
1256
  packageConditions.push(packageCondition);
1291
1257
  }
1292
- });
1258
+ }
1293
1259
  return packageConditions;
1294
1260
  };
1295
1261
 
@@ -1416,7 +1382,7 @@ const createPackageImportNotDefinedError = (specifier, {
1416
1382
  const isSpecifierForNodeBuiltin = specifier => {
1417
1383
  return specifier.startsWith("node:") || NODE_BUILTIN_MODULE_SPECIFIERS.includes(specifier);
1418
1384
  };
1419
- const NODE_BUILTIN_MODULE_SPECIFIERS = ["assert", "assert/strict", "async_hooks", "buffer_ieee754", "buffer", "child_process", "cluster", "console", "constants", "crypto", "_debugger", "dgram", "dns", "domain", "events", "freelist", "fs", "fs/promises", "_http_agent", "_http_client", "_http_common", "_http_incoming", "_http_outgoing", "_http_server", "http", "http2", "https", "inspector", "_linklist", "module", "net", "node-inspect/lib/_inspect", "node-inspect/lib/internal/inspect_client", "node-inspect/lib/internal/inspect_repl", "os", "path", "perf_hooks", "process", "punycode", "querystring", "readline", "repl", "smalloc", "_stream_duplex", "_stream_transform", "_stream_wrap", "_stream_passthrough", "_stream_readable", "_stream_writable", "stream", "stream/promises", "string_decoder", "sys", "timers", "_tls_common", "_tls_legacy", "_tls_wrap", "tls", "trace_events", "tty", "url", "util", "v8/tools/arguments", "v8/tools/codemap", "v8/tools/consarray", "v8/tools/csvparser", "v8/tools/logreader", "v8/tools/profile_view", "v8/tools/splaytree", "v8", "vm", "worker_threads", "zlib",
1385
+ const NODE_BUILTIN_MODULE_SPECIFIERS = ["assert", "assert/strict", "async_hooks", "buffer_ieee754", "buffer", "child_process", "cluster", "console", "constants", "crypto", "_debugger", "dgram", "dns", "domain", "events", "freelist", "fs", "fsevents", "fs/promises", "_http_agent", "_http_client", "_http_common", "_http_incoming", "_http_outgoing", "_http_server", "http", "http2", "https", "inspector", "_linklist", "module", "net", "node-inspect/lib/_inspect", "node-inspect/lib/internal/inspect_client", "node-inspect/lib/internal/inspect_repl", "os", "path", "perf_hooks", "process", "punycode", "querystring", "readline", "repl", "smalloc", "_stream_duplex", "_stream_transform", "_stream_wrap", "_stream_passthrough", "_stream_readable", "_stream_writable", "stream", "stream/promises", "string_decoder", "sys", "timers", "_tls_common", "_tls_legacy", "_tls_wrap", "tls", "trace_events", "tty", "url", "util", "v8/tools/arguments", "v8/tools/codemap", "v8/tools/consarray", "v8/tools/csvparser", "v8/tools/logreader", "v8/tools/profile_view", "v8/tools/splaytree", "v8", "vm", "worker_threads", "zlib",
1420
1386
  // global is special
1421
1387
  "global"];
1422
1388
 
@@ -2195,13 +2161,14 @@ const jsenvPluginSupervisor = ({
2195
2161
  return {
2196
2162
  name: "jsenv:supervisor",
2197
2163
  appliesDuring: "dev",
2198
- serve: async serveInfo => {
2199
- if (serveInfo.request.pathname.startsWith("/__get_cause_trace__/")) {
2200
- const {
2201
- pathname,
2202
- searchParams
2203
- } = new URL(serveInfo.request.url);
2204
- const urlWithLineAndColumn = decodeURIComponent(pathname.slice("/__get_cause_trace__/".length));
2164
+ devServerRoutes: [{
2165
+ endpoint: "GET /.internal/get_cause_trace/*",
2166
+ description: "Return source code around the place an error was thrown.",
2167
+ declarationSource: import.meta.url,
2168
+ fetch: async (request, {
2169
+ kitchen
2170
+ }) => {
2171
+ const urlWithLineAndColumn = decodeURIComponent(request.params[0]);
2205
2172
  const result = resolveUrlSite(urlWithLineAndColumn);
2206
2173
  if (!result) {
2207
2174
  return {
@@ -2214,7 +2181,7 @@ const jsenvPluginSupervisor = ({
2214
2181
  line,
2215
2182
  column
2216
2183
  } = result;
2217
- const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
2184
+ const urlInfo = kitchen.graph.getUrlInfo(file);
2218
2185
  if (!urlInfo) {
2219
2186
  return {
2220
2187
  status: 204,
@@ -2226,7 +2193,7 @@ const jsenvPluginSupervisor = ({
2226
2193
  if (!urlInfo.originalContent) {
2227
2194
  await urlInfo.fetchContent();
2228
2195
  }
2229
- const remap = searchParams.has("remap");
2196
+ const remap = request.searchParams.has("remap");
2230
2197
  if (remap) {
2231
2198
  const sourcemap = urlInfo.sourcemap;
2232
2199
  if (sourcemap) {
@@ -2265,8 +2232,14 @@ const jsenvPluginSupervisor = ({
2265
2232
  body: causeTraceJson
2266
2233
  };
2267
2234
  }
2268
- if (serveInfo.request.pathname.startsWith("/__get_error_cause__/")) {
2269
- let file = serveInfo.request.pathname.slice("/__get_error_cause__/".length);
2235
+ }, {
2236
+ endpoint: "GET /.internal/get_error_cause/*",
2237
+ description: "Return the error that occured when a file was served by jsenv dev server or null.",
2238
+ declarationSource: import.meta.url,
2239
+ fetch: (request, {
2240
+ kitchen
2241
+ }) => {
2242
+ let file = decodeURIComponent(request.params[0]);
2270
2243
  file = decodeURIComponent(file);
2271
2244
  if (!file) {
2272
2245
  return {
@@ -2278,12 +2251,12 @@ const jsenvPluginSupervisor = ({
2278
2251
  url
2279
2252
  } = applyNodeEsmResolution({
2280
2253
  conditions: [],
2281
- parentUrl: serveInfo.rootDirectoryUrl,
2254
+ parentUrl: kitchen.context.rootDirectoryUrl,
2282
2255
  specifier: file
2283
2256
  });
2284
2257
  file = url;
2285
2258
  const getErrorCauseInfo = () => {
2286
- const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
2259
+ const urlInfo = kitchen.graph.getUrlInfo(file);
2287
2260
  if (!urlInfo) {
2288
2261
  return null;
2289
2262
  }
@@ -2321,31 +2294,7 @@ const jsenvPluginSupervisor = ({
2321
2294
  body
2322
2295
  };
2323
2296
  }
2324
- if (serveInfo.request.pathname.startsWith("/__open_in_editor__/")) {
2325
- let file = serveInfo.request.pathname.slice("/__open_in_editor__/".length);
2326
- file = decodeURIComponent(file);
2327
- if (!file) {
2328
- return {
2329
- status: 400,
2330
- body: "Missing file in url"
2331
- };
2332
- }
2333
- const fileUrl = new URL(file, serveInfo.rootDirectoryUrl);
2334
- const filePath = urlToFileSystemPath(fileUrl);
2335
- const require = createRequire(import.meta.url);
2336
- const launch = require("launch-editor");
2337
- launch(filePath, () => {
2338
- // ignore error for now
2339
- });
2340
- return {
2341
- status: 200,
2342
- headers: {
2343
- "cache-control": "no-store"
2344
- }
2345
- };
2346
- }
2347
- return null;
2348
- },
2297
+ }],
2349
2298
  transformUrlContent: {
2350
2299
  html: htmlUrlInfo => {
2351
2300
  const supervisorFileReference = htmlUrlInfo.dependencies.inject({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/plugin-supervisor",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,10 +26,9 @@
26
26
  "/dist/"
27
27
  ],
28
28
  "dependencies": {
29
- "@jsenv/ast": "6.5.1",
30
- "@jsenv/urls": "2.6.0",
31
- "@jsenv/sourcemap": "1.2.30",
32
- "launch-editor": "2.9.1"
29
+ "@jsenv/ast": "6.6.0",
30
+ "@jsenv/urls": "2.6.1",
31
+ "@jsenv/sourcemap": "1.3.0"
33
32
  },
34
33
  "scripts": {
35
34
  "build": "node ./scripts/build.mjs",
@@ -1041,7 +1041,7 @@ window.__supervisor__ = (() => {
1041
1041
  const errorCauseFile = exception.site.ownerSite
1042
1042
  ? exception.site.ownerSite.url
1043
1043
  : exception.site.url;
1044
- const errorCauseAPIUrl = `/__get_error_cause__/${encodeURIComponent(
1044
+ const errorCauseAPIUrl = `/.internal/get_error_cause/${encodeURIComponent(
1045
1045
  errorCauseFile,
1046
1046
  )}`;
1047
1047
  const response = await window.fetch(errorCauseAPIUrl);
@@ -1064,7 +1064,7 @@ window.__supervisor__ = (() => {
1064
1064
  column: exception.site.ownerSite.inlineColumn,
1065
1065
  })
1066
1066
  : stringifyUrlSite(exception.site);
1067
- const errorTraceAPIUrl = `/__get_cause_trace__/${encodeURIComponent(
1067
+ const errorTraceAPIUrl = `/.internal/get_cause_trace/${encodeURIComponent(
1068
1068
  errorTraceFile,
1069
1069
  )}`;
1070
1070
  const urlToFetch = new URL(errorTraceAPIUrl, window.origin);
@@ -1107,7 +1107,7 @@ window.__supervisor__ = (() => {
1107
1107
  return {
1108
1108
  href:
1109
1109
  urlSite.url.startsWith("file:") && openInEditor
1110
- ? `javascript:window.fetch('/__open_in_editor__/${encodeURIComponent(
1110
+ ? `javascript:window.fetch('/.internal/open_file/${encodeURIComponent(
1111
1111
  urlWithLineAndColumn,
1112
1112
  )}')`
1113
1113
  : urlSite.url,
@@ -6,8 +6,7 @@
6
6
  import { generateContentFrame } from "@jsenv/humanize";
7
7
  import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
8
8
  import { getOriginalPosition } from "@jsenv/sourcemap";
9
- import { injectQueryParams, urlToFileSystemPath } from "@jsenv/urls";
10
- import { createRequire } from "node:module";
9
+ import { injectQueryParams } from "@jsenv/urls";
11
10
  import {
12
11
  injectSupervisorIntoHTML,
13
12
  supervisorFileUrl,
@@ -71,161 +70,140 @@ export const jsenvPluginSupervisor = ({
71
70
  return {
72
71
  name: "jsenv:supervisor",
73
72
  appliesDuring: "dev",
74
- serve: async (serveInfo) => {
75
- if (serveInfo.request.pathname.startsWith("/__get_cause_trace__/")) {
76
- const { pathname, searchParams } = new URL(serveInfo.request.url);
77
- const urlWithLineAndColumn = decodeURIComponent(
78
- pathname.slice("/__get_cause_trace__/".length),
79
- );
80
- const result = resolveUrlSite(urlWithLineAndColumn);
81
- if (!result) {
82
- return {
83
- status: 400,
84
- body: "Missing line and column in url",
85
- };
86
- }
87
- let { file, line, column } = result;
88
- const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
89
- if (!urlInfo) {
90
- return {
91
- status: 204,
92
- headers: {
93
- "cache-control": "no-store",
94
- },
95
- };
96
- }
97
- if (!urlInfo.originalContent) {
98
- await urlInfo.fetchContent();
99
- }
100
- const remap = searchParams.has("remap");
101
- if (remap) {
102
- const sourcemap = urlInfo.sourcemap;
103
- if (sourcemap) {
104
- const original = getOriginalPosition({
105
- sourcemap,
106
- url: file,
107
- line,
108
- column,
109
- });
110
- if (original.line !== null) {
111
- line = original.line;
112
- if (original.column !== null) {
113
- column = original.column;
73
+ devServerRoutes: [
74
+ {
75
+ endpoint: "GET /.internal/get_cause_trace/*",
76
+ description: "Return source code around the place an error was thrown.",
77
+ declarationSource: import.meta.url,
78
+ fetch: async (request, { kitchen }) => {
79
+ const urlWithLineAndColumn = decodeURIComponent(request.params[0]);
80
+ const result = resolveUrlSite(urlWithLineAndColumn);
81
+ if (!result) {
82
+ return {
83
+ status: 400,
84
+ body: "Missing line and column in url",
85
+ };
86
+ }
87
+ let { file, line, column } = result;
88
+ const urlInfo = kitchen.graph.getUrlInfo(file);
89
+ if (!urlInfo) {
90
+ return {
91
+ status: 204,
92
+ headers: {
93
+ "cache-control": "no-store",
94
+ },
95
+ };
96
+ }
97
+ if (!urlInfo.originalContent) {
98
+ await urlInfo.fetchContent();
99
+ }
100
+ const remap = request.searchParams.has("remap");
101
+ if (remap) {
102
+ const sourcemap = urlInfo.sourcemap;
103
+ if (sourcemap) {
104
+ const original = getOriginalPosition({
105
+ sourcemap,
106
+ url: file,
107
+ line,
108
+ column,
109
+ });
110
+ if (original.line !== null) {
111
+ line = original.line;
112
+ if (original.column !== null) {
113
+ column = original.column;
114
+ }
114
115
  }
115
116
  }
116
117
  }
117
- }
118
- const causeTrace = {
119
- url: file,
120
- line,
121
- column,
122
- codeFrame: generateContentFrame({
118
+ const causeTrace = {
119
+ url: file,
123
120
  line,
124
121
  column,
125
- content: urlInfo.originalContent,
126
- }),
127
- };
128
- const causeTraceJson = JSON.stringify(causeTrace, null, " ");
129
- return {
130
- status: 200,
131
- headers: {
132
- "cache-control": "no-store",
133
- "content-type": "application/json",
134
- "content-length": Buffer.byteLength(causeTraceJson),
135
- },
136
- body: causeTraceJson,
137
- };
138
- }
139
- if (serveInfo.request.pathname.startsWith("/__get_error_cause__/")) {
140
- let file = serveInfo.request.pathname.slice(
141
- "/__get_error_cause__/".length,
142
- );
143
- file = decodeURIComponent(file);
144
- if (!file) {
122
+ codeFrame: generateContentFrame({
123
+ line,
124
+ column,
125
+ content: urlInfo.originalContent,
126
+ }),
127
+ };
128
+ const causeTraceJson = JSON.stringify(causeTrace, null, " ");
145
129
  return {
146
- status: 400,
147
- body: "Missing file in url",
130
+ status: 200,
131
+ headers: {
132
+ "cache-control": "no-store",
133
+ "content-type": "application/json",
134
+ "content-length": Buffer.byteLength(causeTraceJson),
135
+ },
136
+ body: causeTraceJson,
148
137
  };
149
- }
150
- const { url } = applyNodeEsmResolution({
151
- conditions: [],
152
- parentUrl: serveInfo.rootDirectoryUrl,
153
- specifier: file,
154
- });
155
- file = url;
156
- const getErrorCauseInfo = () => {
157
- const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
158
- if (!urlInfo) {
159
- return null;
160
- }
161
- const { error } = urlInfo;
162
- if (error) {
163
- return error;
138
+ },
139
+ },
140
+ {
141
+ endpoint: "GET /.internal/get_error_cause/*",
142
+ description:
143
+ "Return the error that occured when a file was served by jsenv dev server or null.",
144
+ declarationSource: import.meta.url,
145
+ fetch: (request, { kitchen }) => {
146
+ let file = decodeURIComponent(request.params[0]);
147
+ file = decodeURIComponent(file);
148
+ if (!file) {
149
+ return {
150
+ status: 400,
151
+ body: "Missing file in url",
152
+ };
164
153
  }
165
- // search in direct dependencies (404 or 500)
166
- for (const referenceToOther of urlInfo.referenceToOthersSet) {
167
- const referencedUrlInfo = referenceToOther.urlInfo;
168
- if (referencedUrlInfo.error) {
169
- return referencedUrlInfo.error;
154
+ const { url } = applyNodeEsmResolution({
155
+ conditions: [],
156
+ parentUrl: kitchen.context.rootDirectoryUrl,
157
+ specifier: file,
158
+ });
159
+ file = url;
160
+ const getErrorCauseInfo = () => {
161
+ const urlInfo = kitchen.graph.getUrlInfo(file);
162
+ if (!urlInfo) {
163
+ return null;
170
164
  }
171
- }
172
- return null;
173
- };
174
- const causeInfo = getErrorCauseInfo();
175
- const body = JSON.stringify(
176
- causeInfo
177
- ? {
178
- code: causeInfo.code,
179
- name: causeInfo.name,
180
- message: causeInfo.message,
181
- reason: causeInfo.reason,
182
- stack: errorBaseUrl
183
- ? `stack mocked for snapshot`
184
- : causeInfo.stack,
185
- trace: causeInfo.trace,
165
+ const { error } = urlInfo;
166
+ if (error) {
167
+ return error;
168
+ }
169
+ // search in direct dependencies (404 or 500)
170
+ for (const referenceToOther of urlInfo.referenceToOthersSet) {
171
+ const referencedUrlInfo = referenceToOther.urlInfo;
172
+ if (referencedUrlInfo.error) {
173
+ return referencedUrlInfo.error;
186
174
  }
187
- : null,
188
- null,
189
- " ",
190
- );
191
- return {
192
- status: 200,
193
- headers: {
194
- "cache-control": "no-store",
195
- "content-type": "application/json",
196
- "content-length": Buffer.byteLength(body),
197
- },
198
- body,
199
- };
200
- }
201
- if (serveInfo.request.pathname.startsWith("/__open_in_editor__/")) {
202
- let file = serveInfo.request.pathname.slice(
203
- "/__open_in_editor__/".length,
204
- );
205
- file = decodeURIComponent(file);
206
-
207
- if (!file) {
175
+ }
176
+ return null;
177
+ };
178
+ const causeInfo = getErrorCauseInfo();
179
+ const body = JSON.stringify(
180
+ causeInfo
181
+ ? {
182
+ code: causeInfo.code,
183
+ name: causeInfo.name,
184
+ message: causeInfo.message,
185
+ reason: causeInfo.reason,
186
+ stack: errorBaseUrl
187
+ ? `stack mocked for snapshot`
188
+ : causeInfo.stack,
189
+ trace: causeInfo.trace,
190
+ }
191
+ : null,
192
+ null,
193
+ " ",
194
+ );
208
195
  return {
209
- status: 400,
210
- body: "Missing file in url",
196
+ status: 200,
197
+ headers: {
198
+ "cache-control": "no-store",
199
+ "content-type": "application/json",
200
+ "content-length": Buffer.byteLength(body),
201
+ },
202
+ body,
211
203
  };
212
- }
213
- const fileUrl = new URL(file, serveInfo.rootDirectoryUrl);
214
- const filePath = urlToFileSystemPath(fileUrl);
215
- const require = createRequire(import.meta.url);
216
- const launch = require("launch-editor");
217
- launch(filePath, () => {
218
- // ignore error for now
219
- });
220
- return {
221
- status: 200,
222
- headers: {
223
- "cache-control": "no-store",
224
- },
225
- };
226
- }
227
- return null;
228
- },
204
+ },
205
+ },
206
+ ],
229
207
  transformUrlContent: {
230
208
  html: (htmlUrlInfo) => {
231
209
  const supervisorFileReference = htmlUrlInfo.dependencies.inject({