diff --git a/package-lock.json b/package-lock.json index 513c81ef..f5f933f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,6 @@ "json-colorizer": "^3.0.1", "open": "^10.1.0", "parse-domain": "^8.2.2", - "rollup": "^4.52.4", "simple-git": "^3.25.0", "string-template": "^1.0.0", "uuid": "^9.0.1" @@ -5710,83 +5709,6 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", - "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", - "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.52.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", @@ -5794,6 +5716,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5807,6 +5730,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5820,6 +5744,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5833,6 +5758,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5846,6 +5772,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5859,6 +5786,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5872,6 +5800,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5885,6 +5814,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5898,6 +5828,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5911,6 +5842,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5924,6 +5856,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5937,6 +5870,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5950,6 +5884,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5963,6 +5898,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5976,6 +5912,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5989,6 +5926,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6002,6 +5940,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6015,6 +5954,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6028,6 +5968,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6041,6 +5982,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6054,6 +5996,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6067,6 +6010,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6950,16 +6894,6 @@ "@types/send": "*" } }, - "node_modules/@types/fs-extra": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", - "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -7228,13 +7162,6 @@ "node": ">= 0.12" } }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/send": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz", @@ -9942,16 +9869,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/default-browser": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", @@ -11506,6 +11423,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -12688,13 +12606,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true, - "license": "MIT" - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -12736,16 +12647,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, "node_modules/is-regexp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", @@ -16273,8 +16174,8 @@ "version": "4.52.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -16311,60 +16212,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rollup-plugin-copy": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz", - "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/fs-extra": "^8.0.1", - "colorette": "^1.1.0", - "fs-extra": "^8.1.0", - "globby": "10.0.1", - "is-plain-object": "^3.0.0" - }, - "engines": { - "node": ">=8.3" - } - }, - "node_modules/rollup-plugin-copy/node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/rollup-plugin-copy/node_modules/globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup-plugin-copy/node_modules/is-plain-object": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", - "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -19588,106 +19435,8 @@ "version": "1.0.0", "license": "AGPL-3.0-only", "devDependencies": { - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2", - "rollup": "^3.21.4", - "rollup-plugin-copy": "^3.4.0" - } - }, - "src/backend-core-0/node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "src/backend-core-0/node_modules/brace-expansion": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "src/backend-core-0/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "src/backend-core-0/node_modules/glob": { - "version": "8.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "src/backend-core-0/node_modules/magic-string": { - "version": "0.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "src/backend-core-0/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "src/backend-core-0/node_modules/rollup": { - "version": "3.29.5", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" } }, "src/backend/node_modules/@smithy/abort-controller": { @@ -20305,41 +20054,15 @@ "sinon": "^17.0.1" }, "devDependencies": { - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2", + "copy-webpack-plugin": "^12.0.2", "mocha": "^10.8.2", - "rollup": "^3.29.5", - "rollup-plugin-copy": "^3.4.0" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" }, "optionalDependencies": { "node-pty": "^1.0.0" } }, - "src/phoenix/node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "src/phoenix/node_modules/@sinonjs/fake-timers": { "version": "11.3.1", "license": "BSD-3-Clause", @@ -20347,77 +20070,6 @@ "@sinonjs/commons": "^3.0.1" } }, - "src/phoenix/node_modules/brace-expansion": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "src/phoenix/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "src/phoenix/node_modules/glob": { - "version": "8.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "src/phoenix/node_modules/magic-string": { - "version": "0.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "src/phoenix/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "src/phoenix/node_modules/rollup": { - "version": "3.29.5", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "src/phoenix/node_modules/sinon": { "version": "17.0.1", "license": "BSD-3-Clause", @@ -20477,108 +20129,11 @@ "@xterm/xterm": "^5.5.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2", + "copy-webpack-plugin": "^12.0.2", "http-server": "^14.1.1", "mocha": "^10.8.2", - "rollup": "^3.29.5", - "rollup-plugin-copy": "^3.4.0" - } - }, - "src/terminal/node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "src/terminal/node_modules/brace-expansion": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "src/terminal/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "src/terminal/node_modules/glob": { - "version": "8.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "src/terminal/node_modules/magic-string": { - "version": "0.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "src/terminal/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "src/terminal/node_modules/rollup": { - "version": "3.29.5", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" } }, "src/useapi": { diff --git a/package.json b/package.json index 66d875ec..c80a3839 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "json-colorizer": "^3.0.1", "open": "^10.1.0", "parse-domain": "^8.2.2", - "rollup": "^4.52.4", "simple-git": "^3.25.0", "string-template": "^1.0.0", "uuid": "^9.0.1" @@ -90,4 +89,4 @@ "engines": { "node": ">=20.19.5" } -} +} \ No newline at end of file diff --git a/src/backend-core-0/package.json b/src/backend-core-0/package.json index d232c284..c1781052 100644 --- a/src/backend-core-0/package.json +++ b/src/backend-core-0/package.json @@ -4,7 +4,7 @@ "description": "The ugly name is intentional. We prefer to refactor incrementally which means we need a way to \"re-core\" the backend, and we may do this more than once simultaneously (hence it's `0` right now).", "type": "module", "scripts": { - "build": "rollup -c", + "build": "webpack", "prepare": "npm run build", "test": "echo \"Error: no test specified\" && exit 1" }, @@ -15,11 +15,8 @@ } }, "devDependencies": { - "rollup": "^3.21.4", - "rollup-plugin-copy": "^3.4.0", - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" }, "keywords": [], "author": "", diff --git a/src/backend-core-0/rollup.config.js b/src/backend-core-0/rollup.config.js deleted file mode 100644 index 838911a3..00000000 --- a/src/backend-core-0/rollup.config.js +++ /dev/null @@ -1,27 +0,0 @@ -import { defineConfig } from 'rollup'; -import { nodeResolve } from '@rollup/plugin-node-resolve'; -import commonjs from '@rollup/plugin-commonjs'; - -export default defineConfig([ - // ESM build - { - input: 'src/exports.js', - output: { - dir: 'dist/esm', - format: 'es', - preserveModules: true - }, - plugins: [nodeResolve()] - }, - // CJS build - { - input: 'src/exports.js', - output: { - dir: 'dist/cjs', - format: 'cjs', - preserveModules: true, - entryFileNames: '[name].cjs', - }, - plugins: [nodeResolve(), commonjs()] - } -]); diff --git a/src/backend-core-0/src/exports.js b/src/backend-core-0/src/exports.js index f331a946..86e2b491 100644 --- a/src/backend-core-0/src/exports.js +++ b/src/backend-core-0/src/exports.js @@ -1 +1 @@ -export * as validation from './pdim/validation'; +export * as validation from './pdim/validation.js'; diff --git a/src/backend-core-0/webpack.config.js b/src/backend-core-0/webpack.config.js new file mode 100644 index 00000000..7f2ce504 --- /dev/null +++ b/src/backend-core-0/webpack.config.js @@ -0,0 +1,54 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// ESM build +const esmConfig = { + mode: 'production', + entry: './src/exports.js', + experiments: { + outputModule: true, + }, + output: { + path: path.resolve(__dirname, 'dist/esm'), + filename: 'exports.js', + module: true, + library: { + type: 'module', + }, + }, + optimization: { + minimize: false, + }, + resolve: { + extensions: ['.js', '.mjs'], + fullySpecified: false, + }, + target: 'node', +}; + +// CJS build +const cjsConfig = { + mode: 'production', + entry: './src/exports.js', + output: { + path: path.resolve(__dirname, 'dist/cjs'), + filename: 'exports.cjs', + library: { + type: 'commonjs2', + }, + }, + optimization: { + minimize: false, + }, + resolve: { + extensions: ['.js', '.mjs'], + fullySpecified: false, + }, + target: 'node', +}; + +export default [esmConfig, cjsConfig]; + diff --git a/src/backend/src/modules/selfhosted/DevWatcherService.js b/src/backend/src/modules/selfhosted/DevWatcherService.js index a3fac7c1..81b97fd4 100644 --- a/src/backend/src/modules/selfhosted/DevWatcherService.js +++ b/src/backend/src/modules/selfhosted/DevWatcherService.js @@ -21,7 +21,6 @@ const BaseService = require("../../services/BaseService"); const path_ = require('node:path'); const fs = require('node:fs'); -const rollupModule = require("rollup"); class ProxyLogger { constructor (log) { @@ -70,9 +69,8 @@ class DevWatcherService extends BaseService { async ['__on_ready.webserver'] () { const svc_process = this.services.get('process'); - let { root, commands, webpack, rollup } = this.args; + let { root, commands, webpack } = this.args; if ( ! webpack ) webpack = []; - if ( ! rollup ) rollup = []; let promises = []; for ( const entry of commands ) { @@ -86,10 +84,6 @@ class DevWatcherService extends BaseService { const p = this.start_a_webpack_watcher_(entry); promises.push(p); } - for ( const entry of rollup ) { - const p = this.start_a_rollup_watcher_(entry); - promises.push(p); - } await Promise.all(promises); // It's difficult to tell when webpack is "done" its first @@ -152,8 +146,37 @@ class DevWatcherService extends BaseService { if ( entry.env ) { oldEnv = process.env; const newEnv = Object.create(process.env); + let global_config = null; + try { + const svc_config = this.services.get('config'); + global_config = svc_config ? svc_config.get('global_config') : null; + } catch (e) { + // Config service not available yet, will use null + } + for ( const k in entry.env ) { - newEnv[k] = entry.env[k]; + const envValue = entry.env[k]; + // If it's a function, call it with the config, otherwise use the value directly + if ( typeof envValue === 'function' ) { + try { + const result = envValue({ global_config: global_config }); + // Only set the env var if we got a non-empty result + // This allows the webpack config to use its fallback values + if ( result ) { + newEnv[k] = result; + } + } catch (e) { + // If config is not available yet, don't set the env var + // This allows the webpack config to use its fallback values from config files + // Only log if it's not a null/undefined access error (which is expected) + if ( !e.message.includes('Cannot read properties of null') && + !e.message.includes('Cannot read properties of undefined') ) { + this.log.warn(`Could not evaluate env function for ${k}: ${e.message}`); + } + } + } else { + newEnv[k] = envValue; + } } process.env = newEnv; // Yep, it totally lets us do this } @@ -185,10 +208,13 @@ class DevWatcherService extends BaseService { hideSuccess = true; } if (err || stats.hasErrors()) { - this.log.error(`error information: ${entry.directory} using Webpack`, { - err, - stats, - }); + // Extract error information without serializing the entire stats object + const errorInfo = { + err: err ? err.message : null, + errors: stats.compilation?.errors?.map(e => e.message) || [], + warnings: stats.compilation?.warnings?.map(w => w.message) || [], + }; + this.log.error(`error information: ${entry.directory} using Webpack`, errorInfo); this.log.error(`❌ failed to update ${entry.directory} using Webpack`); } else { // Normally success messages aren't important, but sometimes it takes @@ -200,83 +226,6 @@ class DevWatcherService extends BaseService { } }); } - - async start_a_rollup_watcher_ (entry) { - const possibleConfigNames = [ - ['rollup.config.js', 'package.json'], - ['rollup.config.cjs', 'commonjs'], - ['rollup.config.mjs', 'module'], - ]; - - const { - configjsPath: rollupConfigPath, - moduleType, - } = await this.get_configjs({ - directory: entry.directory, - configIsFor: 'rollup', // for error message - possibleConfigNames, - }); - - const updateRollupPaths = (config, newBase) => { - const onoutput = o => ({ ...o, file: o.file ? path_.join(newBase, o.file) : o.file }); - return { - ...config, - input: path_.join(newBase, config.input), - output: Array.isArray(config.output) - ? config.output.map(onoutput) - : onoutput(config.output), - }; - }; - - let oldEnv; - - if ( entry.env ) { - oldEnv = process.env; - const newEnv = Object.create(process.env); - for ( const k in entry.env ) { - newEnv[k] = entry.env[k]; - } - process.env = newEnv; // Yep, it totally lets us do this - } - - let rollupConfig = moduleType === 'module' - ? (await import(rollupConfigPath)).default - : require(rollupConfigPath); - - if ( oldEnv ) process.env = oldEnv; - - rollupConfig = updateRollupPaths( - rollupConfig, - path_.join(this.args.root, entry.directory), - ); - // rollupConfig.watch = true; // I mean why can't it just... - - const watcher = rollupModule.watch(rollupConfig); - let errorAfterLastEnd = false; - let firstEvent = true; - watcher.on('event', (event) => { - if ( event.code === 'END' ) { - let hideSuccess = false; - if ( firstEvent ) { - firstEvent = false; - hideSuccess = true; - } - if ( errorAfterLastEnd ) { - errorAfterLastEnd = false; - return; - } - if ( ! hideSuccess ) { - this.log.info(`✅ updated ${entry.directory} using Rollup`); - } - } else if ( event.code === 'ERROR' ) { - this.log.error(`error information: ${entry.directory} using Rollup`, { - event, - }); - this.log.error(`❌ failed to update ${entry.directory} using Rollup`); - errorAfterLastEnd = true; - } - }); - } }; module.exports = DevWatcherService; diff --git a/src/backend/src/modules/selfhosted/SelfHostedModule.js b/src/backend/src/modules/selfhosted/SelfHostedModule.js index 4273f52b..58081f11 100644 --- a/src/backend/src/modules/selfhosted/SelfHostedModule.js +++ b/src/backend/src/modules/selfhosted/SelfHostedModule.js @@ -51,23 +51,21 @@ class SelfHostedModule extends AdvancedBase { { services.registerService('__dev-watcher', DevWatcherService, { root: path_.resolve(__dirname, RELATIVE_PATH), - rollup: [ + webpack: [ { name: 'phoenix', directory: 'src/phoenix', env: { - PUTER_JS_URL: ({ global_config: config }) => config.origin + '/sdk/puter.dev.js', + PUTER_JS_URL: ({ global_config: config }) => config?.origin ? config.origin + '/puter.js/v2' : '', }, }, { name: 'terminal', directory: 'src/terminal', env: { - PUTER_JS_URL: ({ global_config: config }) => config.origin + '/sdk/puter.dev.js', + PUTER_JS_URL: ({ global_config: config }) => config?.origin ? config.origin + '/puter.js/v2' : '', }, }, - ], - webpack: [ { name: 'puter.js', directory: 'src/puter-js', @@ -76,8 +74,8 @@ class SelfHostedModule extends AdvancedBase { config.devtool = 'source-map'; }, env: { - PUTER_ORIGIN: ({ global_config: config }) => config.origin, - PUTER_API_ORIGIN: ({ global_config: config }) => config.api_base_url, + PUTER_ORIGIN: ({ global_config: config }) => config?.origin || '', + PUTER_API_ORIGIN: ({ global_config: config }) => config?.api_base_url || '', }, }, { diff --git a/src/phoenix/assets/index.html b/src/phoenix/assets/index.html index 76977f65..f1464a44 100644 --- a/src/phoenix/assets/index.html +++ b/src/phoenix/assets/index.html @@ -1,5 +1,6 @@ + @@ -10,8 +11,20 @@ - + + \ No newline at end of file diff --git a/src/phoenix/config/dev.js b/src/phoenix/config/dev.js index f7affea1..435ad3d8 100644 --- a/src/phoenix/config/dev.js +++ b/src/phoenix/config/dev.js @@ -19,5 +19,5 @@ globalThis.__CONFIG__ = { "origin": "https://puter.local:8080", "shell.href": "https://puter.local:8081", - "sdk_url": "http://puter.localhost:4100/sdk/puter.js", + "sdk_url": "http://puter.localhost:4100/puter.js/v2", }; diff --git a/src/phoenix/package.json b/src/phoenix/package.json index 0aeed3bd..5cba6422 100644 --- a/src/phoenix/package.json +++ b/src/phoenix/package.json @@ -10,12 +10,10 @@ "license": "AGPL-3.0-only", "type": "module", "devDependencies": { - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2", + "copy-webpack-plugin": "^12.0.2", "mocha": "^10.8.2", - "rollup": "^3.29.5", - "rollup-plugin-copy": "^3.4.0" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" }, "dependencies": { "@pkgjs/parseargs": "^0.11.0", @@ -36,4 +34,4 @@ "packages/strataparse", "packages/contextlink" ] -} +} \ No newline at end of file diff --git a/src/phoenix/rollup.config.js b/src/phoenix/rollup.config.js deleted file mode 100644 index 4a647289..00000000 --- a/src/phoenix/rollup.config.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { nodeResolve } from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs'; -import copy from 'rollup-plugin-copy'; -import process from 'node:process'; -import path from 'node:path'; - -const configFile = process.env.CONFIG_FILE ?? 'config/dev.js'; -await import(`./${configFile}`); - -export default { - input: "src/main_puter.js", - output: { - file: "dist/bundle.js", - format: "iife", - strict: false, - }, - plugins: [ - nodeResolve({ - rootDir: path.join(process.cwd(), '..'), - }), - commonjs(), - copy({ - targets: [ - { - src: 'assets/index.html', - dest: 'dist', - transform: (contents, name) => { - return contents.toString().replace('__SDK_URL__', - process.env.PUTER_JS_URL ?? globalThis.__CONFIG__.sdk_url); - } - }, - { src: 'assets/shell.html', dest: 'dist' }, - { src: configFile, dest: 'dist', rename: 'config.js' } - ] - }), - ] -} diff --git a/src/phoenix/run.json5 b/src/phoenix/run.json5 index a7f23ac7..0f13e2cd 100644 --- a/src/phoenix/run.json5 +++ b/src/phoenix/run.json5 @@ -7,8 +7,8 @@ command: 'npx http-server -p 8080', }, { - name: 'shell.rollup', - command: 'npx rollup -c rollup.config.js --watch', + name: 'shell.webpack', + command: 'npx webpack --watch', pwd: '.' }, ], diff --git a/src/phoenix/src/platform/browser/node-stubs/child_process.js b/src/phoenix/src/platform/browser/node-stubs/child_process.js new file mode 100644 index 00000000..c39cf94e --- /dev/null +++ b/src/phoenix/src/platform/browser/node-stubs/child_process.js @@ -0,0 +1,3 @@ +// Browser stub for node:child_process - not used in browser builds +export default {}; + diff --git a/src/phoenix/src/platform/browser/node-stubs/node-pty.js b/src/phoenix/src/platform/browser/node-stubs/node-pty.js new file mode 100644 index 00000000..55b55859 --- /dev/null +++ b/src/phoenix/src/platform/browser/node-stubs/node-pty.js @@ -0,0 +1,3 @@ +// Browser stub for node-pty - not used in browser builds +export default {}; + diff --git a/src/phoenix/src/platform/browser/node-stubs/path.js b/src/phoenix/src/platform/browser/node-stubs/path.js new file mode 100644 index 00000000..a74f262d --- /dev/null +++ b/src/phoenix/src/platform/browser/node-stubs/path.js @@ -0,0 +1,3 @@ +// Browser stub for node:path - not used in browser builds +export default {}; + diff --git a/src/phoenix/src/platform/browser/node-stubs/process.js b/src/phoenix/src/platform/browser/node-stubs/process.js new file mode 100644 index 00000000..7ebeddca --- /dev/null +++ b/src/phoenix/src/platform/browser/node-stubs/process.js @@ -0,0 +1,3 @@ +// Browser stub for node:process - not used in browser builds +export default {}; + diff --git a/src/phoenix/src/platform/browser/node-stubs/stream.js b/src/phoenix/src/platform/browser/node-stubs/stream.js new file mode 100644 index 00000000..a36492c0 --- /dev/null +++ b/src/phoenix/src/platform/browser/node-stubs/stream.js @@ -0,0 +1,3 @@ +// Browser stub for node:stream - not used in browser builds +export default {}; + diff --git a/src/phoenix/src/puter-shell/main.js b/src/phoenix/src/puter-shell/main.js index bec1e19c..4fcff89b 100644 --- a/src/phoenix/src/puter-shell/main.js +++ b/src/phoenix/src/puter-shell/main.js @@ -16,28 +16,28 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import builtins from './coreutils/__exports__.js'; import ReadlineLib from "../ansi-shell/readline/readline.js"; +import builtins from './coreutils/__exports__.js'; // TODO: auto-gen argument parser registry from files +import { libs } from '@heyputer/putility'; +import { BetterReader } from 'dev-pty'; +import { ANSIShell } from "../ansi-shell/ANSIShell.js"; import SimpleArgParser from "../ansi-shell/arg-parsers/simple-parser.js"; import ErrorsDecorator from "../ansi-shell/decorators/errors.js"; -import { ANSIShell } from "../ansi-shell/ANSIShell.js"; -import { libs } from '@heyputer/putility'; -const { Context } = libs.context; -import { SHELL_VERSIONS } from "../meta/versions.js"; -import { PuterShellParser } from "../ansi-shell/parsing/PuterShellParser.js"; -import { BuiltinCommandProvider } from "./providers/BuiltinCommandProvider.js"; -import { CreateChatHistoryPlugin } from './plugins/ChatHistoryPlugin.js'; -import { Pipe } from '../ansi-shell/pipeline/Pipe.js'; -import { Coupler } from '../ansi-shell/pipeline/Coupler.js'; -import { BetterReader } from 'dev-pty'; import { MultiWriter } from '../ansi-shell/ioutil/MultiWriter.js'; +import { PuterShellParser } from "../ansi-shell/parsing/PuterShellParser.js"; +import { Coupler } from '../ansi-shell/pipeline/Coupler.js'; +import { Pipe } from '../ansi-shell/pipeline/Pipe.js'; +import { SHELL_VERSIONS } from "../meta/versions.js"; +import { CreateChatHistoryPlugin } from './plugins/ChatHistoryPlugin.js'; +import { BuiltinCommandProvider } from "./providers/BuiltinCommandProvider.js"; import { CompositeCommandProvider } from './providers/CompositeCommandProvider.js'; -import { ScriptCommandProvider } from './providers/ScriptCommandProvider.js'; -import { PuterAppCommandProvider } from './providers/PuterAppCommandProvider.js'; import { EmuCommandProvider } from './providers/EmuCommandProvider.js'; import { PDECommandProvider } from './providers/PDECommandProvider.js'; +import { PuterAppCommandProvider } from './providers/PuterAppCommandProvider.js'; +import { ScriptCommandProvider } from './providers/ScriptCommandProvider.js'; +const { Context } = libs.context; const argparser_registry = { [SimpleArgParser.name]: SimpleArgParser @@ -78,7 +78,7 @@ export const launchPuterShell = async (ctx) => { } // PathCommandProvider is only compatible with node.js for now - // HACK: The import path is split to fool rollup into not including it. + // HACK: The import path is split to fool webpack into not including it. const { PathCommandProvider } = (ctx.platform.name === 'node') ? await import('./providers/' + 'PathCommandProvider.js') : { PathCommandProvider: null }; diff --git a/src/phoenix/tools/build_tar.sh b/src/phoenix/tools/build_tar.sh index 274e1924..c6644a63 100755 --- a/src/phoenix/tools/build_tar.sh +++ b/src/phoenix/tools/build_tar.sh @@ -4,7 +4,7 @@ if [ $(basename "$(pwd)") != "phoenix" ]; then fi export CONFIG_FILE='config/release.js' -npx rollup -c rollup.config.js +npx webpack if [ -d ./release ]; then rm -rf ./release/* diff --git a/src/phoenix/webpack-resolve-extensions-plugin.js b/src/phoenix/webpack-resolve-extensions-plugin.js new file mode 100644 index 00000000..2f8e41d8 --- /dev/null +++ b/src/phoenix/webpack-resolve-extensions-plugin.js @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import fs from 'node:fs'; +import path from 'node:path'; + +class ResolveExtensionsPlugin { + apply(compiler) { + compiler.hooks.normalModuleFactory.tap('ResolveExtensionsPlugin', (nmf) => { + nmf.hooks.beforeResolve.tap('ResolveExtensionsPlugin', (data) => { + if (!data) return; + + // Skip if already has an extension + if (data.request.match(/\.(js|mjs|json|ts|tsx|css|html)$/)) { + return; + } + + const context = data.context || compiler.options.context || process.cwd(); + let requestPath; + + // Handle relative imports (starting with ./ or ../) + if (data.request.startsWith('.')) { + requestPath = path.resolve(context, data.request); + } + // Handle package subpath imports (like @heyputer/putility/src/libs/promise) + // Only add .js if there's a subpath (more than just the package name) + else if (data.request.includes('/') && !data.request.startsWith('/') && !data.request.startsWith('.')) { + const parts = data.request.split('/'); + // If there are more than 2 parts (e.g., @scope/pkg/path/to/file), it's a subpath + // Scoped packages like @heyputer/putility have 2 parts for the name + if (data.request.startsWith('@')) { + // Scoped package: @scope/pkg/path -> needs 3+ parts for subpath + if (parts.length > 2) { + data.request = data.request + '.js'; + return; + } + } else { + // Non-scoped package: pkg/path -> needs 2+ parts for subpath + if (parts.length > 1) { + data.request = data.request + '.js'; + return; + } + } + return; // Top-level package import, don't modify + } else { + return; // Not a relative or package subpath import + } + + // Check if .js file exists (for relative imports) + const jsPath = requestPath + '.js'; + if (fs.existsSync(jsPath)) { + data.request = data.request + '.js'; + return; + } + + // Check if it's a directory with index.js + if (fs.existsSync(requestPath) && fs.statSync(requestPath).isDirectory()) { + const indexPath = path.join(requestPath, 'index.js'); + if (fs.existsSync(indexPath)) { + data.request = data.request + '/index.js'; + } + } + }); + }); + } +} + +export default ResolveExtensionsPlugin; + diff --git a/src/phoenix/webpack.config.js b/src/phoenix/webpack.config.js new file mode 100644 index 00000000..18d07c95 --- /dev/null +++ b/src/phoenix/webpack.config.js @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import CopyWebpackPlugin from 'copy-webpack-plugin'; +import fs from 'node:fs'; +import path from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; +import webpack from 'webpack'; +import ResolveExtensionsPlugin from './webpack-resolve-extensions-plugin.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const configFile = process.env.CONFIG_FILE ?? 'config/dev.js'; +const configPath = path.resolve(__dirname, configFile); + +// Read and evaluate config file manually to avoid webpack processing it +const configContent = fs.readFileSync(configPath, 'utf-8'); +// Create a safe context to evaluate the config +const configContext = { globalThis: { __CONFIG__: {} } }; +// Evaluate the config file in a controlled way +eval(configContent.replace(/globalThis\.__CONFIG__/g, 'configContext.globalThis.__CONFIG__')); + +// Capture config values at build time +const sdkUrl = process.env.PUTER_JS_URL ?? + (configContext.globalThis.__CONFIG__?.sdk_url ?? ''); + +export default { + mode: 'development', + entry: './src/main_puter.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'bundle.js', + iife: true, + }, + resolve: { + modules: [path.resolve(__dirname, '..'), 'node_modules'], + extensions: ['.js', '.mjs', '.json'], + }, + plugins: [ + new ResolveExtensionsPlugin(), + // Replace Node.js built-ins with empty modules for browser builds + new webpack.NormalModuleReplacementPlugin( + /^node:path$/, + path.resolve(__dirname, 'src/platform/browser/node-stubs/path.js') + ), + new webpack.NormalModuleReplacementPlugin( + /^node:child_process$/, + path.resolve(__dirname, 'src/platform/browser/node-stubs/child_process.js') + ), + new webpack.NormalModuleReplacementPlugin( + /^node:stream$/, + path.resolve(__dirname, 'src/platform/browser/node-stubs/stream.js') + ), + new webpack.NormalModuleReplacementPlugin( + /^node:process$/, + path.resolve(__dirname, 'src/platform/browser/node-stubs/process.js') + ), + new webpack.NormalModuleReplacementPlugin( + /^node-pty$/, + path.resolve(__dirname, 'src/platform/browser/node-stubs/node-pty.js') + ), + new CopyWebpackPlugin({ + patterns: [ + { + from: 'assets/index.html', + to: 'index.html', + transform: (content) => { + return content.toString().replace('__SDK_URL__', sdkUrl); + }, + }, + { + from: configFile, + to: 'config.js', + }, + ], + }), + ], +}; + diff --git a/src/terminal/assets/index.html b/src/terminal/assets/index.html index a6636576..28156957 100644 --- a/src/terminal/assets/index.html +++ b/src/terminal/assets/index.html @@ -1,5 +1,6 @@ + @@ -13,10 +14,23 @@ + - + + \ No newline at end of file diff --git a/src/terminal/config/dev.js b/src/terminal/config/dev.js index 07f2384b..50f78f58 100644 --- a/src/terminal/config/dev.js +++ b/src/terminal/config/dev.js @@ -18,5 +18,5 @@ */ globalThis.__CONFIG__ = { "origin": "http://127.0.0.1:8082", - "sdk_url": "http://puter.localhost:4100/sdk/puter.js", + "sdk_url": "http://puter.localhost:4100/puter.js/v2", }; diff --git a/src/terminal/package.json b/src/terminal/package.json index a5b817fb..222223ac 100644 --- a/src/terminal/package.json +++ b/src/terminal/package.json @@ -10,17 +10,15 @@ "license": "AGPL-3.0-only", "type": "module", "devDependencies": { - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^5.0.2", + "copy-webpack-plugin": "^12.0.2", "http-server": "^14.1.1", "mocha": "^10.8.2", - "rollup": "^3.29.5", - "rollup-plugin-copy": "^3.4.0" + "webpack": "^5.88.2", + "webpack-cli": "^5.1.1" }, "dependencies": { "@xterm/addon-fit": "^0.10.0", "@xterm/addon-image": "^0.8.0", "@xterm/xterm": "^5.5.0" } -} +} \ No newline at end of file diff --git a/src/terminal/rollup.config.js b/src/terminal/rollup.config.js deleted file mode 100644 index 075871c7..00000000 --- a/src/terminal/rollup.config.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { nodeResolve } from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs'; -import copy from 'rollup-plugin-copy'; -import process from 'node:process'; -import path from 'node:path'; - -const configFile = process.env.CONFIG_FILE ?? 'config/dev.js'; -await import(`./${configFile}`); - -export default { - input: "src/main.js", - output: { - file: "dist/bundle.js", - format: "iife" - }, - plugins: [ - nodeResolve({ - rootDir: path.join(process.cwd(), '..'), - }), - commonjs(), - copy({ - targets: [ - { - src: 'assets/index.html', - dest: 'dist', - transform: (contents, name) => { - return contents.toString().replace('__SDK_URL__', - process.env.PUTER_JS_URL ?? globalThis.__CONFIG__.sdk_url); - } - }, - { src: 'assets/shell.html', dest: 'dist' }, - { src: 'assets/normalize.css', dest: 'dist' }, - { src: 'assets/style.css', dest: 'dist' }, - - // We add this manually because there's no way to be sure - // _which_ node_modules directory is the correct one, since - // support for workspaces is under-documented and people may - // be using package managers other than npm. - { src: 'assets/xterm.css', dest: 'dist' }, - // { src: 'node_modules/xterm/css/xterm.css', dest: 'dist' }, - - { src: configFile, dest: 'dist', rename: 'config.js' } - ] - }), - ] -} diff --git a/src/terminal/run-http.json5 b/src/terminal/run-http.json5 index e2d07e61..32cfb156 100644 --- a/src/terminal/run-http.json5 +++ b/src/terminal/run-http.json5 @@ -6,9 +6,9 @@ command: 'npx http-server -p 8082', }, { - name: 'term.rollup', + name: 'term.webpack', pwd: '.', - command: 'npx rollup -c rollup.config.js --watch', + command: 'npx webpack --watch', }, ] } diff --git a/src/terminal/run-https.json5 b/src/terminal/run-https.json5 index 21f24df4..478d7434 100644 --- a/src/terminal/run-https.json5 +++ b/src/terminal/run-https.json5 @@ -6,9 +6,9 @@ command: 'npx http-server -p 8082 -S -C "{cert}" -K "{key}"', }, { - name: 'term.rollup', + name: 'term.webpack', pwd: '.', - command: 'npx rollup -c rollup.config.js --watch', + command: 'npx webpack --watch', }, ] } diff --git a/src/terminal/run-phoenix-http.json5 b/src/terminal/run-phoenix-http.json5 index e5b3a285..506c5636 100644 --- a/src/terminal/run-phoenix-http.json5 +++ b/src/terminal/run-phoenix-http.json5 @@ -2,22 +2,22 @@ init: [ { pwd: '.', - command: 'npx rollup -c rollup.config.js' + command: 'npx webpack' }, { pwd: '../phoenix', - command: 'npx rollup -c rollup.config.js' + command: 'npx webpack' }, ], services: [ { - name: 'term.rollup', + name: 'term.webpack', pwd: '.', - command: 'npx rollup -c rollup.config.js --watch', + command: 'npx webpack --watch', }, { - name: 'shell.rollup', - command: 'npx rollup -c rollup.config.js --watch', + name: 'shell.webpack', + command: 'npx webpack --watch', pwd: '../phoenix' }, { diff --git a/src/terminal/run.json5 b/src/terminal/run.json5 index 5b746048..477a153d 100644 --- a/src/terminal/run.json5 +++ b/src/terminal/run.json5 @@ -11,13 +11,13 @@ command: 'npx http-server -p 8080 -S -C "{cert}" -K "{key}"', }, { - name: 'term.rollup', - command: 'npx rollup -c rollup.config.js --watch', + name: 'term.webpack', + command: 'npx webpack --watch', pwd: '.' }, { - name: 'ansi.rollup', - command: 'npx rollup -c rollup.config.js --watch', + name: 'ansi.webpack', + command: 'npx webpack --watch', pwd: '../phoenix' }, ] diff --git a/src/terminal/webpack-resolve-extensions-plugin.js b/src/terminal/webpack-resolve-extensions-plugin.js new file mode 100644 index 00000000..2f8e41d8 --- /dev/null +++ b/src/terminal/webpack-resolve-extensions-plugin.js @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import fs from 'node:fs'; +import path from 'node:path'; + +class ResolveExtensionsPlugin { + apply(compiler) { + compiler.hooks.normalModuleFactory.tap('ResolveExtensionsPlugin', (nmf) => { + nmf.hooks.beforeResolve.tap('ResolveExtensionsPlugin', (data) => { + if (!data) return; + + // Skip if already has an extension + if (data.request.match(/\.(js|mjs|json|ts|tsx|css|html)$/)) { + return; + } + + const context = data.context || compiler.options.context || process.cwd(); + let requestPath; + + // Handle relative imports (starting with ./ or ../) + if (data.request.startsWith('.')) { + requestPath = path.resolve(context, data.request); + } + // Handle package subpath imports (like @heyputer/putility/src/libs/promise) + // Only add .js if there's a subpath (more than just the package name) + else if (data.request.includes('/') && !data.request.startsWith('/') && !data.request.startsWith('.')) { + const parts = data.request.split('/'); + // If there are more than 2 parts (e.g., @scope/pkg/path/to/file), it's a subpath + // Scoped packages like @heyputer/putility have 2 parts for the name + if (data.request.startsWith('@')) { + // Scoped package: @scope/pkg/path -> needs 3+ parts for subpath + if (parts.length > 2) { + data.request = data.request + '.js'; + return; + } + } else { + // Non-scoped package: pkg/path -> needs 2+ parts for subpath + if (parts.length > 1) { + data.request = data.request + '.js'; + return; + } + } + return; // Top-level package import, don't modify + } else { + return; // Not a relative or package subpath import + } + + // Check if .js file exists (for relative imports) + const jsPath = requestPath + '.js'; + if (fs.existsSync(jsPath)) { + data.request = data.request + '.js'; + return; + } + + // Check if it's a directory with index.js + if (fs.existsSync(requestPath) && fs.statSync(requestPath).isDirectory()) { + const indexPath = path.join(requestPath, 'index.js'); + if (fs.existsSync(indexPath)) { + data.request = data.request + '/index.js'; + } + } + }); + }); + } +} + +export default ResolveExtensionsPlugin; + diff --git a/src/terminal/webpack.config.js b/src/terminal/webpack.config.js new file mode 100644 index 00000000..07b26a51 --- /dev/null +++ b/src/terminal/webpack.config.js @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import CopyWebpackPlugin from 'copy-webpack-plugin'; +import fs from 'node:fs'; +import path from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; +import ResolveExtensionsPlugin from './webpack-resolve-extensions-plugin.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const configFile = process.env.CONFIG_FILE ?? 'config/dev.js'; +const configPath = path.resolve(__dirname, configFile); + +// Read and evaluate config file manually to avoid webpack processing it +const configContent = fs.readFileSync(configPath, 'utf-8'); +// Create a safe context to evaluate the config +const configContext = { globalThis: { __CONFIG__: {} } }; +// Evaluate the config file in a controlled way +eval(configContent.replace(/globalThis\.__CONFIG__/g, 'configContext.globalThis.__CONFIG__')); + +// Capture config values at build time +const sdkUrl = process.env.PUTER_JS_URL ?? + (configContext.globalThis.__CONFIG__?.sdk_url ?? ''); + +export default { + mode: 'development', + entry: './src/main.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'bundle.js', + iife: true, + }, + resolve: { + modules: [path.resolve(__dirname, '..'), 'node_modules'], + extensions: ['.js', '.mjs', '.json'], + }, + plugins: [ + new ResolveExtensionsPlugin(), + new CopyWebpackPlugin({ + patterns: [ + { + from: 'assets/index.html', + to: 'index.html', + transform: (content) => { + return content.toString().replace('__SDK_URL__', sdkUrl); + }, + }, + { from: 'assets/normalize.css', to: 'normalize.css' }, + { from: 'assets/style.css', to: 'style.css' }, + { from: 'assets/xterm.css', to: 'xterm.css' }, + { + from: configFile, + to: 'config.js', + }, + ], + }), + ], +}; +