Repository: pyscript/pyscript (language: python)

Issue:
PyEditor not playing well with raw JSON as config value
We never thought about enabling *just JSON* as `config` attribute value, we just assumed the best way to go was to point at a config file: https://github.com/pyscript/pyscript/blob/main/pyscript.core/src/plugins/py-editor.js#L39-L46

Turns out, we're missing users' expectations in doing so, so this should likely be fixed/improved.



Discussion / hints:

Fix patch:
diff --git a/pyscript.core/package-lock.json b/pyscript.core/package-lock.json
index 472a23558b5..457c1ccd2b8 100644
--- a/pyscript.core/package-lock.json
+++ b/pyscript.core/package-lock.json
@@ -1,17 +1,17 @@
 {
     "name": "@pyscript/core",
-    "version": "0.4.50",
+    "version": "0.4.52",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "@pyscript/core",
-            "version": "0.4.50",
+            "version": "0.4.52",
             "license": "APACHE-2.0",
             "dependencies": {
                 "@ungap/with-resolvers": "^0.1.0",
                 "basic-devtools": "^0.1.6",
-                "polyscript": "^0.13.5",
+                "polyscript": "^0.13.7",
                 "sticky-module": "^0.1.1",
                 "to-json-callback": "^0.1.1",
                 "type-checked-collections": "^0.1.7"
@@ -21,7 +21,7 @@
                 "@codemirror/lang-python": "^6.1.6",
                 "@codemirror/language": "^6.10.2",
                 "@codemirror/state": "^6.4.1",
-                "@codemirror/view": "^6.28.1",
+                "@codemirror/view": "^6.28.2",
                 "@playwright/test": "^1.44.1",
                 "@rollup/plugin-commonjs": "^26.0.1",
                 "@rollup/plugin-node-resolve": "^15.2.3",
@@ -29,7 +29,7 @@
                 "@webreflection/toml-j0.4": "^1.1.3",
                 "@xterm/addon-fit": "^0.10.0",
                 "@xterm/addon-web-links": "^0.11.0",
-                "bun": "^1.1.14",
+                "bun": "^1.1.16",
                 "chokidar": "^3.6.0",
                 "codemirror": "^6.0.1",
                 "eslint": "^9.5.0",
@@ -38,7 +38,7 @@
                 "rollup-plugin-postcss": "^4.0.2",
                 "rollup-plugin-string": "^3.0.0",
                 "static-handler": "^0.4.3",
-                "typescript": "^5.4.5",
+                "typescript": "^5.5.2",
                 "xterm": "^5.3.0",
                 "xterm-readline": "^1.1.1"
             }
@@ -136,9 +136,9 @@
             "license": "MIT"
         },
         "node_modules/@codemirror/view": {
-            "version": "6.28.1",
-            "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.1.tgz",
-            "integrity": "sha512-BUWr+zCJpMkA/u69HlJmR+YkV4yPpM81HeMkOMZuwFa8iM5uJdEPKAs1icIRZKkKmy0Ub1x9/G3PQLTXdpBxrQ==",
+            "version": "6.28.2",
+            "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.2.tgz",
+            "integrity": "sha512-A3DmyVfjgPsGIjiJqM/zvODUAPQdQl3ci0ghehYNnbt5x+o76xq+dL5+mMBuysDXnI3kapgOkoeJ0sbtL/3qPw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -462,9 +462,9 @@
             }
         },
         "node_modules/@oven/bun-darwin-aarch64": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.14.tgz",
-            "integrity": "sha512-zdgLlQ9+SUOgJzTMQyb0lnX2MRtFgVApXPR9c0lSVUqPbfcGogVDRuNFWdYK96wjUkrCJIvYeu5rbMGcnJD1Qg==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.16.tgz",
+            "integrity": "sha512-a5lnLoyyw24n0uvVSSJVT8kZjA7m3xO2FRBenpr+01A+SIkA8q255ybEBEz+7X30M5ZhYJwb11KgkScd0MB8Mg==",
             "cpu": [
                 "arm64"
             ],
@@ -476,9 +476,9 @@
             ]
         },
         "node_modules/@oven/bun-darwin-x64": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.14.tgz",
-            "integrity": "sha512-CEoFw0udQRann0Vj3Et1/nW6MV3EY/kZ+lNkSCCmFEvq1HDLB+Wbicgnt9GbEElw6XXXKm4FdxMYnOJzfeanYQ==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.16.tgz",
+            "integrity": "sha512-LYm6KnALYdDJEaxV1HYWIttgQMECMV5akvlnKULDYXp2anxjQDYGoZ4VpVwdDiKel3m/pnG0RSPLDHiX5NCYWg==",
             "cpu": [
                 "x64"
             ],
@@ -490,9 +490,9 @@
             ]
         },
         "node_modules/@oven/bun-darwin-x64-baseline": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.14.tgz",
-            "integrity": "sha512-k1vKXmOQ9+Rdj6dkgPIo0MWKmEf9+CmjyD2GZkRM6dxufiytNSuE5yT8FQMtb2Yg1I8OFH/+kUiNxn2eIKurRw==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.16.tgz",
+            "integrity": "sha512-NwnowvNIwT9JsLVQ8YgjzobvVYxC3F3bHN7jGTSX6b5ogLQ+LGzRlzFfnRJNV9JbyLLYeA7jQAS0CPvQoon6gQ==",
             "cpu": [
                 "x64"
             ],
@@ -504,9 +504,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-aarch64": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.14.tgz",
-            "integrity": "sha512-uHI7jk47C6wwG/y90W35NttyDrKLWum1pa5PfpuMi8+LpxnRGi0doGXN73RwdJy+qnYp2OjJTo60X++GMn9GmA==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.16.tgz",
+            "integrity": "sha512-RiUVrMLuROwezg8iTnTgbkvPz3k7G6o07WGVEXVFr6umxlaRc8jB2uVlc2BCrPtJtm27iJJpu7SnwpHg+Rr8Qw==",
             "cpu": [
                 "arm64"
             ],
@@ -518,9 +518,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-x64": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.14.tgz",
-            "integrity": "sha512-t2b6pDSlV2Uke6ON5eSx1hk/o+f4s8Nr+E1djx9fNqrvz58UF4zmilQoEKDhciuRUKvhMkroddiORpxIMiKIjA==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.16.tgz",
+            "integrity": "sha512-T6YDz/KnbH/FZH+2QI3C3CZcGqlGe2Nmk5haMvWPlW7y6B/ejQ84/Y88FNxD7V9rSLlnY+PZX5IQjN0rZ/CaHw==",
             "cpu": [
                 "x64"
             ],
@@ -532,9 +532,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-x64-baseline": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.14.tgz",
-            "integrity": "sha512-7otawHLy8ec0iN0wr7sznkOpMhofZCfJeA4vWp+5D/yhXg8ZxVaK7xJ1aWBlBLHAMX8tWTkrUjB6X2iQFtvZvQ==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.16.tgz",
+            "integrity": "sha512-AWD3Kmb7gvlVqyW8qk/2MbHPS/HzsoNYz0SVjKiJMMzDbRE7cILk5OSYafi+iSnJKy1Qw7p25LP6LpkGzrBnyA==",
             "cpu": [
                 "x64"
             ],
@@ -546,9 +546,9 @@
             ]
         },
         "node_modules/@oven/bun-windows-x64": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.14.tgz",
-            "integrity": "sha512-hZ+Z0zgO6FM63U99wkF0YvTLm/Tcfa4ue5U9JOGc8K05DLBS4gHp6f0bngzd3EvIEz+mfc+zcYPR954dYHT9AA==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.16.tgz",
+            "integrity": "sha512-HMcwQq0lvqSbbXMqrUhLIwhOAMdt5IUCTPDkcMEPKQpWk7FUTfLkeH/8928kqpVmN7LHHH7I9PqMY7Q/Q3gZBA==",
             "cpu": [
                 "x64"
             ],
@@ -560,9 +560,9 @@
             ]
         },
         "node_modules/@oven/bun-windows-x64-baseline": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.14.tgz",
-            "integrity": "sha512-oK7y0q5sICni6771q+xvJ40dqzg0l+x2IdkN8V2I5QMzQCqFIVPhwPmOX5+2JsMp9ILQtYeioyL60kCDgIguDw==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.16.tgz",
+            "integrity": "sha512-SspbjEgeXh7NkB61rhHcQDGqWl/nPQcn7NKb5wkxZyDmrwITciq2J8iaYsw/WEyYUFubjkjvpJala+cGS7voLA==",
             "cpu": [
                 "x64"
             ],
@@ -1202,9 +1202,9 @@
             }
         },
         "node_modules/bun": {
-            "version": "1.1.14",
-            "resolved": "https://registry.npmjs.org/bun/-/bun-1.1.14.tgz",
-            "integrity": "sha512-LqbB6Xr8bU6D9K18UOrzmLLPYOS9CQ3SGW+JvTUli/eYW4y70yzdCr6JZiw3pk0V8ZqHn9Kmg3c8/7rF2XIM8g==",
+            "version": "1.1.16",
+            "resolved": "https://registry.npmjs.org/bun/-/bun-1.1.16.tgz",
+            "integrity": "sha512-t2AwDuJsLA3cBAxNQv/hJ66SLGtVkKFjrxdpcztkUwjVst6G9ynWiVwQOlg6VSN7niF2EZptTvDg6Jb+MKEGMQ==",
             "cpu": [
                 "arm64",
                 "x64"
@@ -1222,14 +1222,14 @@
                 "bunx": "bin/bun.exe"
             },
             "optionalDependencies": {
-                "@oven/bun-darwin-aarch64": "1.1.14",
-                "@oven/bun-darwin-x64": "1.1.14",
-                "@oven/bun-darwin-x64-baseline": "1.1.14",
-                "@oven/bun-linux-aarch64": "1.1.14",
-                "@oven/bun-linux-x64": "1.1.14",
-                "@oven/bun-linux-x64-baseline": "1.1.14",
-                "@oven/bun-windows-x64": "1.1.14",
-                "@oven/bun-windows-x64-baseline": "1.1.14"
+                "@oven/bun-darwin-aarch64": "1.1.16",
+                "@oven/bun-darwin-x64": "1.1.16",
+                "@oven/bun-darwin-x64-baseline": "1.1.16",
+                "@oven/bun-linux-aarch64": "1.1.16",
+                "@oven/bun-linux-x64": "1.1.16",
+                "@oven/bun-linux-x64-baseline": "1.1.16",
+                "@oven/bun-windows-x64": "1.1.16",
+                "@oven/bun-windows-x64-baseline": "1.1.16"
             }
         },
         "node_modules/callsites": {
@@ -2918,9 +2918,9 @@
             }
         },
         "node_modules/polyscript": {
-            "version": "0.13.5",
-            "resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.13.5.tgz",
-            "integrity": "sha512-PwXWnhLbOMtvZWFIN271JhaN7KnxESaMtv9Rcdrq1TKTCMnkz9idvYb3Od1iumBJlr49lLlwyUKeGb423rFR4w==",
+            "version": "0.13.7",
+            "resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.13.7.tgz",
+            "integrity": "sha512-GVJHVw3EjNgWyZIN1yKVd2AtzF+ARwYGYvzN5VHO0WqWXL3w+8CifQIbEDgBgvalOWfF/YxyK4C+0LKVx9lnGA==",
             "license": "APACHE-2.0",
             "dependencies": {
                 "@ungap/structured-clone": "^1.2.0",
@@ -4178,9 +4178,9 @@
             "license": "ISC"
         },
         "node_modules/typescript": {
-            "version": "5.4.5",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-            "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+            "version": "5.5.2",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
+            "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
diff --git a/pyscript.core/package.json b/pyscript.core/package.json
index 402f277194d..03c53082eac 100644
--- a/pyscript.core/package.json
+++ b/pyscript.core/package.json
@@ -1,6 +1,6 @@
 {
     "name": "@pyscript/core",
-    "version": "0.4.50",
+    "version": "0.4.52",
     "type": "module",
     "description": "PyScript",
     "module": "./index.js",
@@ -44,7 +44,7 @@
     "dependencies": {
         "@ungap/with-resolvers": "^0.1.0",
         "basic-devtools": "^0.1.6",
-        "polyscript": "^0.13.5",
+        "polyscript": "^0.13.7",
         "sticky-module": "^0.1.1",
         "to-json-callback": "^0.1.1",
         "type-checked-collections": "^0.1.7"
@@ -54,7 +54,7 @@
         "@codemirror/lang-python": "^6.1.6",
         "@codemirror/language": "^6.10.2",
         "@codemirror/state": "^6.4.1",
-        "@codemirror/view": "^6.28.1",
+        "@codemirror/view": "^6.28.2",
         "@playwright/test": "^1.44.1",
         "@rollup/plugin-commonjs": "^26.0.1",
         "@rollup/plugin-node-resolve": "^15.2.3",
@@ -62,7 +62,7 @@
         "@webreflection/toml-j0.4": "^1.1.3",
         "@xterm/addon-fit": "^0.10.0",
         "@xterm/addon-web-links": "^0.11.0",
-        "bun": "^1.1.14",
+        "bun": "^1.1.16",
         "chokidar": "^3.6.0",
         "codemirror": "^6.0.1",
         "eslint": "^9.5.0",
@@ -71,7 +71,7 @@
         "rollup-plugin-postcss": "^4.0.2",
         "rollup-plugin-string": "^3.0.0",
         "static-handler": "^0.4.3",
-        "typescript": "^5.4.5",
+        "typescript": "^5.5.2",
         "xterm": "^5.3.0",
         "xterm-readline": "^1.1.1"
     },
diff --git a/pyscript.core/src/config.js b/pyscript.core/src/config.js
index ca8d3a46099..040bbbe58c9 100644
--- a/pyscript.core/src/config.js
+++ b/pyscript.core/src/config.js
@@ -45,6 +45,8 @@ const configDetails = async (config, type) => {
 
 const conflictError = (reason) => new Error(`(${CONFLICTING_CODE}): ${reason}`);
 
+const relative_url = (url, base = location.href) => new URL(url, base).href;
+
 const syntaxError = (type, url, { message }) => {
     let str = `(${BAD_CONFIG}): Invalid ${type}`;
     if (url) str += ` @ ${url}`;
@@ -108,7 +110,7 @@ for (const [TYPE] of TYPES) {
     if (!error && config) {
         try {
             const { json, toml, text, url } = await configDetails(config, type);
-            if (url) configURL = new URL(url, location.href).href;
+            if (url) configURL = relative_url(url);
             config = text;
             if (json || type === "json") {
                 try {
@@ -153,4 +155,4 @@ for (const [TYPE] of TYPES) {
     configs.set(TYPE, { config: parsed, configURL, plugins, error });
 }
 
-export default configs;
+export { configs, relative_url };
diff --git a/pyscript.core/src/core.js b/pyscript.core/src/core.js
index 56f7117a954..5a1e3bc70cf 100644
--- a/pyscript.core/src/core.js
+++ b/pyscript.core/src/core.js
@@ -19,7 +19,7 @@ import {
 
 import "./all-done.js";
 import TYPES from "./types.js";
-import configs from "./config.js";
+import { configs, relative_url } from "./config.js";
 import sync from "./sync.js";
 import bootstrapNodeAndPlugins from "./plugins-helper.js";
 import { ErrorCode } from "./exceptions.js";
@@ -84,6 +84,7 @@ const [
 
 export {
     TYPES,
+    relative_url,
     exportedPyWorker as PyWorker,
     exportedMPWorker as MPWorker,
     exportedHooks as hooks,
@@ -92,7 +93,7 @@ export {
 };
 
 export const offline_interpreter = (config) =>
-    config?.interpreter && new URL(config.interpreter, location.href).href;
+    config?.interpreter && relative_url(config.interpreter);
 
 const hooked = new Map();
 
diff --git a/pyscript.core/src/plugins/py-editor.js b/pyscript.core/src/plugins/py-editor.js
index 0a0f69a942e..0218162be4e 100644
--- a/pyscript.core/src/plugins/py-editor.js
+++ b/pyscript.core/src/plugins/py-editor.js
@@ -1,6 +1,6 @@
 // PyScript py-editor plugin
 import { Hook, XWorker, dedent, defineProperties } from "polyscript/exports";
-import { TYPES, offline_interpreter, stdlib } from "../core.js";
+import { TYPES, offline_interpreter, relative_url, stdlib } from "../core.js";
 
 const RUN_BUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
 
@@ -37,11 +37,19 @@ async function execute({ currentTarget }) {
         const details = { type: this.interpreter };
         const { config } = this;
         if (config) {
-            details.configURL = config;
-            const { parse } = config.endsWith(".toml")
-                ? await import(/* webpackIgnore: true */ "../3rd-party/toml.js")
-                : JSON;
-            details.config = parse(await fetch(config).then((r) => r.text()));
+            details.configURL = relative_url(config);
+            if (config.endsWith(".toml")) {
+                const [{ parse }, toml] = await Promise.all([
+                    import(/* webpackIgnore: true */ "../3rd-party/toml.js"),
+                    fetch(config).then((r) => r.text()),
+                ]);
+                details.config = parse(toml);
+            } else if (config.endsWith(".json")) {
+                details.config = await fetch(config).then((r) => r.json());
+            } else {
+                details.configURL = relative_url("./config.txt");
+                details.config = JSON.parse(config);
+            }
             details.version = offline_interpreter(details.config);
         } else {
             details.config = {};
@@ -175,9 +183,7 @@ const init = async (script, type, interpreter) => {
         handleEvent: execute,
         interpreter,
         env,
-        config:
-            hasConfig &&
-            new URL(script.getAttribute("config"), location.href).href,
+        config: hasConfig && script.getAttribute("config"),
         get pySrc() {
             return isSetup ? source : editor.state.doc.toString();
         },
diff --git a/pyscript.core/src/plugins/py-terminal.js b/pyscript.core/src/plugins/py-terminal.js
index 4dfc4eb293d..cd61483a488 100644
--- a/pyscript.core/src/plugins/py-terminal.js
+++ b/pyscript.core/src/plugins/py-terminal.js
@@ -1,5 +1,5 @@
 // PyScript py-terminal plugin
-import { TYPES } from "../core.js";
+import { TYPES, relative_url } from "../core.js";
 import { notify } from "./error.js";
 import { customObserver } from "polyscript/exports";
 
@@ -35,7 +35,7 @@ for (const type of TYPES.keys()) {
             document.head.append(
                 Object.assign(document.createElement("link"), {
                     rel: "stylesheet",
-                    href: new URL("./xterm.css", import.meta.url),
+                    href: relative_url("./xterm.css", import.meta.url),
                 }),
             );
         }
diff --git a/pyscript.core/types/config.d.ts b/pyscript.core/types/config.d.ts
index d9c40f26237..deb21b4c77f 100644
--- a/pyscript.core/types/config.d.ts
+++ b/pyscript.core/types/config.d.ts
@@ -1,2 +1,2 @@
-export default configs;
-declare const configs: Map<any, any>;
+export const configs: Map<any, any>;
+export function relative_url(url: any, base?: string): string;
diff --git a/pyscript.core/types/core.d.ts b/pyscript.core/types/core.d.ts
index 142ca999a81..0853d567c54 100644
--- a/pyscript.core/types/core.d.ts
+++ b/pyscript.core/types/core.d.ts
@@ -3,6 +3,7 @@ import { stdlib } from "./stdlib.js";
 import { optional } from "./stdlib.js";
 import { inputFailure } from "./hooks.js";
 import TYPES from "./types.js";
+import { relative_url } from "./config.js";
 /**
  * A `Worker` facade able to bootstrap on the worker thread only a PyScript module.
  * @param {string} file the python file to run ina worker.
@@ -54,4 +55,4 @@ declare const exportedHooks: {
 };
 declare const exportedConfig: {};
 declare const exportedWhenDefined: (type: string) => Promise<any>;
-export { stdlib, optional, inputFailure, TYPES, exportedPyWorker as PyWorker, exportedMPWorker as MPWorker, exportedHooks as hooks, exportedConfig as config, exportedWhenDefined as whenDefined };
+export { stdlib, optional, inputFailure, TYPES, relative_url, exportedPyWorker as PyWorker, exportedMPWorker as MPWorker, exportedHooks as hooks, exportedConfig as config, exportedWhenDefined as whenDefined };
diff --git a/pyscript.core/types/exceptions.d.ts b/pyscript.core/types/exceptions.d.ts
index f13f1fbfa77..fc2db6340b5 100644
--- a/pyscript.core/types/exceptions.d.ts
+++ b/pyscript.core/types/exceptions.d.ts
@@ -53,19 +53,4 @@ export class InstallError extends UserError {
 /**
  * Keys of the ErrorCode object
  */
-export type ErrorCodes = keyof {
-    GENERIC: string;
-    CONFLICTING_CODE: string;
-    BAD_CONFIG: string;
-    MICROPIP_INSTALL_ERROR: string;
-    BAD_PLUGIN_FILE_EXTENSION: string;
-    NO_DEFAULT_EXPORT: string;
-    TOP_LEVEL_AWAIT: string;
-    FETCH_ERROR: string;
-    FETCH_NAME_ERROR: string;
-    FETCH_UNAUTHORIZED_ERROR: string;
-    FETCH_FORBIDDEN_ERROR: string;
-    FETCH_NOT_FOUND_ERROR: string;
-    FETCH_SERVER_ERROR: string;
-    FETCH_UNAVAILABLE_ERROR: string;
-};
+export type ErrorCodes = "GENERIC" | "CONFLICTING_CODE" | "BAD_CONFIG" | "MICROPIP_INSTALL_ERROR" | "BAD_PLUGIN_FILE_EXTENSION" | "NO_DEFAULT_EXPORT" | "TOP_LEVEL_AWAIT" | "FETCH_ERROR" | "FETCH_NAME_ERROR" | "FETCH_UNAUTHORIZED_ERROR" | "FETCH_FORBIDDEN_ERROR" | "FETCH_NOT_FOUND_ERROR" | "FETCH_SERVER_ERROR" | "FETCH_UNAVAILABLE_ERROR";


Test patch:
diff --git a/pyscript.core/test/py-editor/index.html b/pyscript.core/test/py-editor/index.html
index c1b4f57adb4..a0d32b680fe 100644
--- a/pyscript.core/test/py-editor/index.html
+++ b/pyscript.core/test/py-editor/index.html
@@ -29,7 +29,7 @@
     a = 1
   </script>
   <!-- a share-nothing micropython editor -->
-  <script type="mpy-editor" config="./config.toml">
+  <script type="mpy-editor" config='{"js_modules":{"worker":{"https://cdn.jsdelivr.net/npm/html-escaper/+esm":"html_escaper"}}}'>
     from pyscript.js_modules.html_escaper import escape, unescape
     print(unescape(escape("<OK>")))
     b = 2