change build system to rollup

This commit is contained in:
Avad3 2024-07-13 16:30:33 -04:00
parent 5122438c96
commit c3db610837
39 changed files with 2225 additions and 2451 deletions

View file

@ -1,27 +1,27 @@
{ {
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"], "plugins": ["@typescript-eslint"],
"rules": { "rules": {
"no-await-in-loop": "warn", "no-await-in-loop": "warn",
"no-unused-labels": "error", "no-unused-labels": "error",
"no-unused-vars": "error", "no-unused-vars": "error",
"quotes": ["error", "double"], "quotes": ["error", "double"],
"max-lines-per-function": ["error", { "max-lines-per-function": ["error", {
"max": 200, "max": 200,
"skipComments": true "skipComments": true
}], }],
"getter-return": "error", "getter-return": "error",
"newline-before-return": "error", "newline-before-return": "error",
"no-multiple-empty-lines": "error", "no-multiple-empty-lines": "error",
"no-var": "error", "no-var": "error",
"indent": ["warn", 4], "indent": ["warn", 4],
"no-this-before-super": "warn", "no-this-before-super": "warn",
"no-useless-return": "error", "no-useless-return": "error",
"no-shadow": "error", "no-shadow": "error",
"prefer-const": "warn", "prefer-const": "warn",
"no-unreachable": "warn", "no-unreachable": "warn",
"no-undef": "off", "no-undef": "off",
"@typescript-eslint/ban-ts-comment": "off" "@typescript-eslint/ban-ts-comment": "off"
} }
} }

18
.gitignore vendored
View file

@ -1,9 +1,9 @@
node_modules node_modules
dist dist
static/scramjet* static/scramjet*
static/bare-mux.js static/bare-mux.js
static/bare-client.js static/bare-client.js
static/curl-client.js static/curl-client.js
static/epoxy-client.js static/epoxy-client.js
static/bare-mux-worker.js static/bare-mux-worker.js
meta.json meta.json

View file

@ -1,21 +1,21 @@
# Scramjet # Scramjet
Scramjet is an experimental web proxy that aims to be the successor to Ultraviolet. Scramjet is an experimental web proxy that aims to be the successor to Ultraviolet.
It currently does not support most websites due to it being very early in the development stage. It currently does not support most websites due to it being very early in the development stage.
The UI is not finalized and only used as a means to test the web proxy. The UI is not finalized and only used as a means to test the web proxy.
## How to build ## How to build
Running `pnpm dev` will build Scramjet and start a dev server on localhost:1337. If you only want to build the proxy without using the dev server, run `pnpm build`. Running `pnpm dev` will build Scramjet and start a dev server on localhost:1337. If you only want to build the proxy without using the dev server, run `pnpm build`.
## TODO ## TODO
- Finish HTML rewriting - Finish HTML rewriting
- `<script type="importmap"></script>` rewriting - `<script type="importmap"></script>` rewriting
- Make an array of all possible import values and pass the array onto the JS rewriter, then rewrite all the URLs inside of it - Make an array of all possible import values and pass the array onto the JS rewriter, then rewrite all the URLs inside of it
- Finish JS rewriting - Finish JS rewriting
- Only thing rewritten currently are imports and exports - Only thing rewritten currently are imports and exports
- Check imports/exports for values contained in the `importmap` array, don't rewrite the node value if present - Check imports/exports for values contained in the `importmap` array, don't rewrite the node value if present
- Write client APIs - Write client APIs

View file

@ -1,97 +0,0 @@
// import { createServer } from "esbuild-server";
import copy from "esbuild-plugin-copy";
import time from "esbuild-plugin-time";
import { createBareServer } from "@tomphttp/bare-server-node";
import Fastify from "fastify";
import { context } from "esbuild";
import { createServer } from "http";
import fastifyStatic from "@fastify/static";
import { join } from "path";
import { fileURLToPath } from "url";
import "dotenv/config";
const bare = createBareServer("/bare/", {
logErrors: true
});
const fastify = Fastify({
serverFactory: (handler) => {
return createServer()
.on("request", (req, res) => {
if (bare.shouldRoute(req)) {
bare.routeRequest(req, res);
} else {
handler(req, res);
}
}).on("upgrade", (req, socket, head) => {
if (bare.shouldRoute(req)) {
bare.routeUpgrade(req, socket, head);
} else {
socket.end();
}
})
}
});
fastify.register(fastifyStatic, {
root: join(fileURLToPath(new URL(".", import.meta.url)), "./static"),
decorateReply: false
});
//fastify.get("/", {
// })
fastify.listen({
port: 1337
});
const devServer = await context({
entryPoints: {
client: "./src/client/index.ts",
bundle: "./src/bundle/index.ts",
worker: "./src/worker/index.ts",
codecs: "./src/codecs/index.ts",
config: "./src/scramjet.config.ts",
},
entryNames: "scramjet.[name]",
outdir: "./dist",
bundle: true,
sourcemap: true,
logLevel: "info",
format: "esm",
plugins: [
copy({
resolveFrom: "cwd",
assets: [
{
from: ["./node_modules/@mercuryworkshop/bare-mux/dist/index.js"],
to: ["./static/bare-mux.js"],
},
{
from: ["./node_modules/@mercuryworkshop/bare-as-module3/dist/index.mjs"],
to: ["./static/bare-client.js"],
},
{
from: ["./node_modules/@mercuryworkshop/libcurl-transport/dist/index.mjs"],
to: ["./static/curl-client.js"],
},
{
from: ["./node_modules/@mercuryworkshop/epoxy-transport/dist/index.mjs"],
to: ["./static/epoxy-client.js"],
},
{
from: ["./node_modules/@mercuryworkshop/bare-mux/dist/worker.js"],
to: ["./static/bare-mux-worker.js"],
},
{
from: ["./dist/*"],
to: ["./static"]
},
],
}),
time()
],
});
await devServer.watch();

View file

@ -1,26 +0,0 @@
import { build } from "esbuild";
import time from "esbuild-plugin-time";
import { writeFileSync } from "fs"
const scramjetBuild = await build({
entryPoints: {
client: "./src/client/index.ts",
bundle: "./src/bundle/index.ts",
worker: "./src/worker/index.ts",
codecs: "./src/codecs/index.ts",
config: "./src/scramjet.config.ts",
},
entryNames: "scramjet.[name]",
outdir: "./dist",
bundle: true,
plugins: [
time()
],
logLevel: "info",
metafile: true,
treeShaking: true,
minify: true,
format: "esm"
});
writeFileSync("./meta.json", JSON.stringify(scramjetBuild.metafile));

View file

@ -1,7 +1,7 @@
"use strict"; "use strict";
const { resolve } = require("node:path"); const { resolve } = require("node:path");
const scramjetPath = resolve(__dirname, "..", "dist"); const scramjetPath = resolve(__dirname, "..", "dist");
exports.scramjetPath = scramjetPath; exports.scramjetPath = scramjetPath;

6
lib/index.d.ts vendored
View file

@ -1,3 +1,3 @@
declare const scramjetPath: string; declare const scramjetPath: string;
export { scramjetPath }; export { scramjetPath };

View file

@ -9,8 +9,8 @@
"url": "https://github.com/MercuryWorkshop/scramjet" "url": "https://github.com/MercuryWorkshop/scramjet"
}, },
"scripts": { "scripts": {
"build": "node esbuild.js", "build": "rollup -c",
"dev": "node esbuild.dev.js", "dev": "node server.js",
"prepublish": "pnpm build", "prepublish": "pnpm build",
"pub": "pnpm publish --no-git-checks --access public" "pub": "pnpm publish --no-git-checks --access public"
}, },
@ -26,18 +26,20 @@
"@mercuryworkshop/bare-as-module3": "^2.2.2", "@mercuryworkshop/bare-as-module3": "^2.2.2",
"@mercuryworkshop/epoxy-transport": "^2.1.3", "@mercuryworkshop/epoxy-transport": "^2.1.3",
"@mercuryworkshop/libcurl-transport": "^1.3.6", "@mercuryworkshop/libcurl-transport": "^1.3.6",
"@rollup/plugin-inject": "^5.0.5",
"@rollup/plugin-replace": "^5.0.5",
"@tomphttp/bare-server-node": "^2.0.3", "@tomphttp/bare-server-node": "^2.0.3",
"@types/eslint": "^8.56.10", "@types/eslint": "^8.56.10",
"@types/estraverse": "^5.1.7", "@types/estree": "^1.0.5",
"@types/node": "^20.14.10",
"@types/serviceworker": "^0.0.85", "@types/serviceworker": "^0.0.85",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^6.21.0",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"esbuild": "^0.20.2",
"esbuild-plugin-copy": "^2.1.1",
"esbuild-plugin-time": "^1.0.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"fastify": "^4.26.2", "fastify": "^4.26.2",
"rollup": "^4.17.2",
"rollup-plugin-typescript2": "^0.36.0",
"tslib": "^2.6.2", "tslib": "^2.6.2",
"typescript": "^5.4.5" "typescript": "^5.4.5"
}, },
@ -45,11 +47,11 @@
"dependencies": { "dependencies": {
"@mercuryworkshop/bare-mux": "^2.0.2", "@mercuryworkshop/bare-mux": "^2.0.2",
"@webreflection/idb-map": "^0.3.1", "@webreflection/idb-map": "^0.3.1",
"astravel": "^0.6.1",
"astring": "^1.8.6", "astring": "^1.8.6",
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domhandler": "^5.0.3", "domhandler": "^5.0.3",
"domutils": "^3.1.0", "domutils": "^3.1.0",
"estraverse": "^5.3.0",
"htmlparser2": "^9.1.0", "htmlparser2": "^9.1.0",
"meriyah": "^4.4.2" "meriyah": "^4.4.2"
} }

429
pnpm-lock.yaml generated
View file

@ -14,6 +14,9 @@ importers:
'@webreflection/idb-map': '@webreflection/idb-map':
specifier: ^0.3.1 specifier: ^0.3.1
version: 0.3.1 version: 0.3.1
astravel:
specifier: ^0.6.1
version: 0.6.1
astring: astring:
specifier: ^1.8.6 specifier: ^1.8.6
version: 1.8.6 version: 1.8.6
@ -26,9 +29,6 @@ importers:
domutils: domutils:
specifier: ^3.1.0 specifier: ^3.1.0
version: 3.1.0 version: 3.1.0
estraverse:
specifier: ^5.3.0
version: 5.3.0
htmlparser2: htmlparser2:
specifier: ^9.1.0 specifier: ^9.1.0
version: 9.1.0 version: 9.1.0
@ -48,15 +48,24 @@ importers:
'@mercuryworkshop/libcurl-transport': '@mercuryworkshop/libcurl-transport':
specifier: ^1.3.6 specifier: ^1.3.6
version: 1.3.6(typescript@5.4.5) version: 1.3.6(typescript@5.4.5)
'@rollup/plugin-inject':
specifier: ^5.0.5
version: 5.0.5(rollup@4.17.2)
'@rollup/plugin-replace':
specifier: ^5.0.5
version: 5.0.7(rollup@4.17.2)
'@tomphttp/bare-server-node': '@tomphttp/bare-server-node':
specifier: ^2.0.3 specifier: ^2.0.3
version: 2.0.3 version: 2.0.3
'@types/eslint': '@types/eslint':
specifier: ^8.56.10 specifier: ^8.56.10
version: 8.56.10 version: 8.56.10
'@types/estraverse': '@types/estree':
specifier: ^5.1.7 specifier: ^1.0.5
version: 5.1.7 version: 1.0.5
'@types/node':
specifier: ^20.14.10
version: 20.14.10
'@types/serviceworker': '@types/serviceworker':
specifier: ^0.0.85 specifier: ^0.0.85
version: 0.0.85 version: 0.0.85
@ -69,21 +78,18 @@ importers:
dotenv: dotenv:
specifier: ^16.4.5 specifier: ^16.4.5
version: 16.4.5 version: 16.4.5
esbuild:
specifier: ^0.20.2
version: 0.20.2
esbuild-plugin-copy:
specifier: ^2.1.1
version: 2.1.1(esbuild@0.20.2)
esbuild-plugin-time:
specifier: ^1.0.0
version: 1.0.0
eslint: eslint:
specifier: ^8.57.0 specifier: ^8.57.0
version: 8.57.0 version: 8.57.0
fastify: fastify:
specifier: ^4.26.2 specifier: ^4.26.2
version: 4.26.2 version: 4.26.2
rollup:
specifier: ^4.17.2
version: 4.17.2
rollup-plugin-typescript2:
specifier: ^0.36.0
version: 0.36.0(rollup@4.17.2)(typescript@5.4.5)
tslib: tslib:
specifier: ^2.6.2 specifier: ^2.6.2
version: 2.6.2 version: 2.6.2
@ -93,144 +99,6 @@ importers:
packages: packages:
'@esbuild/aix-ppc64@0.20.2':
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.20.2':
resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.20.2':
resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.20.2':
resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.20.2':
resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.20.2':
resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.20.2':
resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.20.2':
resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.20.2':
resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.20.2':
resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.20.2':
resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.20.2':
resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.20.2':
resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.20.2':
resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.20.2':
resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.20.2':
resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.20.2':
resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-x64@0.20.2':
resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-x64@0.20.2':
resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
'@esbuild/sunos-x64@0.20.2':
resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.20.2':
resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.20.2':
resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.20.2':
resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
'@eslint-community/eslint-utils@4.4.0': '@eslint-community/eslint-utils@4.4.0':
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -286,6 +154,9 @@ packages:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'} engines: {node: '>=12'}
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@lukeed/ms@2.0.2': '@lukeed/ms@2.0.2':
resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -321,10 +192,37 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'} engines: {node: '>=14'}
'@rollup/plugin-inject@5.0.5':
resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
'@rollup/plugin-replace@5.0.7':
resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
'@rollup/pluginutils@4.2.1': '@rollup/pluginutils@4.2.1':
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
engines: {node: '>= 8.0.0'} engines: {node: '>= 8.0.0'}
'@rollup/pluginutils@5.1.0':
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
'@rollup/rollup-android-arm-eabi@4.17.2': '@rollup/rollup-android-arm-eabi@4.17.2':
resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==}
cpu: [arm] cpu: [arm]
@ -413,17 +311,14 @@ packages:
'@types/eslint@8.56.10': '@types/eslint@8.56.10':
resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
'@types/estraverse@5.1.7':
resolution: {integrity: sha512-JRVtdKYZz7VkNp7hMC/WKoiZ8DS3byw20ZGoMZ1R8eBrBPIY7iBaDAS1zcrnXQCwK44G4vbXkimeU7R0VLG8UQ==}
'@types/estree@1.0.5': '@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node@20.12.11': '@types/node@20.14.10':
resolution: {integrity: sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==} resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
'@types/resolve@0.0.8': '@types/resolve@0.0.8':
resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
@ -553,10 +448,6 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'} engines: {node: '>=12'}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
archy@1.0.0: archy@1.0.0:
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
@ -567,6 +458,9 @@ packages:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'} engines: {node: '>=8'}
astravel@0.6.1:
resolution: {integrity: sha512-ZIkgWFIV0Yo423Vqalz7VcF+BAiISvSgplnkV2abPGACPFKofsWTcvr9SFyYM/t/vMZWqmdP/Eze6ATX7r84Dg==}
astring@1.8.6: astring@1.8.6:
resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==}
hasBin: true hasBin: true
@ -588,10 +482,6 @@ packages:
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
brace-expansion@1.1.11: brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@ -620,10 +510,6 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'} engines: {node: '>=10'}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
color-convert@2.0.1: color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'} engines: {node: '>=7.0.0'}
@ -707,22 +593,9 @@ packages:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
esbuild-plugin-copy@2.1.1:
resolution: {integrity: sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==}
peerDependencies:
esbuild: '>= 0.14.0'
esbuild-plugin-time@1.0.0:
resolution: {integrity: sha512-I4Shhi0fpgXxSoc34djTHIuhbEzkcBbKKiNtb3LhZe2JEE1vSxXilW+KE0M/KZ4kqORLGgdGCKuJh9CNUL55yw==}
esbuild-plugin-umd-wrapper@2.0.0: esbuild-plugin-umd-wrapper@2.0.0:
resolution: {integrity: sha512-pcu2/lcm29S85VCnSJuValrQ8FqeFJs5VWEwfp7vBRsOHjxZypcxgwXjxDIxDRo17uOcENZIbgz2szjln029eQ==} resolution: {integrity: sha512-pcu2/lcm29S85VCnSJuValrQ8FqeFJs5VWEwfp7vBRsOHjxZypcxgwXjxDIxDRo17uOcENZIbgz2szjln029eQ==}
esbuild@0.20.2:
resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
engines: {node: '>=12'}
hasBin: true
escape-html@1.0.3: escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@ -946,10 +819,6 @@ packages:
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-core-module@2.13.1: is-core-module@2.13.1:
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
@ -1037,6 +906,9 @@ packages:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'} engines: {node: '>=10'}
magic-string@0.30.10:
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
make-dir@3.1.0: make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1075,10 +947,6 @@ packages:
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
on-exit-leak-free@2.1.2: on-exit-leak-free@2.1.2:
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -1184,10 +1052,6 @@ packages:
resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
real-require@0.2.0: real-require@0.2.0:
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
engines: {node: '>= 12.13.0'} engines: {node: '>= 12.13.0'}
@ -1431,75 +1295,6 @@ packages:
snapshots: snapshots:
'@esbuild/aix-ppc64@0.20.2':
optional: true
'@esbuild/android-arm64@0.20.2':
optional: true
'@esbuild/android-arm@0.20.2':
optional: true
'@esbuild/android-x64@0.20.2':
optional: true
'@esbuild/darwin-arm64@0.20.2':
optional: true
'@esbuild/darwin-x64@0.20.2':
optional: true
'@esbuild/freebsd-arm64@0.20.2':
optional: true
'@esbuild/freebsd-x64@0.20.2':
optional: true
'@esbuild/linux-arm64@0.20.2':
optional: true
'@esbuild/linux-arm@0.20.2':
optional: true
'@esbuild/linux-ia32@0.20.2':
optional: true
'@esbuild/linux-loong64@0.20.2':
optional: true
'@esbuild/linux-mips64el@0.20.2':
optional: true
'@esbuild/linux-ppc64@0.20.2':
optional: true
'@esbuild/linux-riscv64@0.20.2':
optional: true
'@esbuild/linux-s390x@0.20.2':
optional: true
'@esbuild/linux-x64@0.20.2':
optional: true
'@esbuild/netbsd-x64@0.20.2':
optional: true
'@esbuild/openbsd-x64@0.20.2':
optional: true
'@esbuild/sunos-x64@0.20.2':
optional: true
'@esbuild/win32-arm64@0.20.2':
optional: true
'@esbuild/win32-ia32@0.20.2':
optional: true
'@esbuild/win32-x64@0.20.2':
optional: true
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
dependencies: dependencies:
eslint: 8.57.0 eslint: 8.57.0
@ -1579,6 +1374,8 @@ snapshots:
wrap-ansi: 8.1.0 wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0 wrap-ansi-cjs: wrap-ansi@7.0.0
'@jridgewell/sourcemap-codec@1.5.0': {}
'@lukeed/ms@2.0.2': {} '@lukeed/ms@2.0.2': {}
'@mercuryworkshop/bare-as-module3@2.2.2': '@mercuryworkshop/bare-as-module3@2.2.2':
@ -1624,11 +1421,34 @@ snapshots:
'@pkgjs/parseargs@0.11.0': '@pkgjs/parseargs@0.11.0':
optional: true optional: true
'@rollup/plugin-inject@5.0.5(rollup@4.17.2)':
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
estree-walker: 2.0.2
magic-string: 0.30.10
optionalDependencies:
rollup: 4.17.2
'@rollup/plugin-replace@5.0.7(rollup@4.17.2)':
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
magic-string: 0.30.10
optionalDependencies:
rollup: 4.17.2
'@rollup/pluginutils@4.2.1': '@rollup/pluginutils@4.2.1':
dependencies: dependencies:
estree-walker: 2.0.2 estree-walker: 2.0.2
picomatch: 2.3.1 picomatch: 2.3.1
'@rollup/pluginutils@5.1.0(rollup@4.17.2)':
dependencies:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
optionalDependencies:
rollup: 4.17.2
'@rollup/rollup-android-arm-eabi@4.17.2': '@rollup/rollup-android-arm-eabi@4.17.2':
optional: true optional: true
@ -1695,21 +1515,17 @@ snapshots:
'@types/estree': 1.0.5 '@types/estree': 1.0.5
'@types/json-schema': 7.0.15 '@types/json-schema': 7.0.15
'@types/estraverse@5.1.7':
dependencies:
'@types/estree': 1.0.5
'@types/estree@1.0.5': {} '@types/estree@1.0.5': {}
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/node@20.12.11': '@types/node@20.14.10':
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 5.26.5
'@types/resolve@0.0.8': '@types/resolve@0.0.8':
dependencies: dependencies:
'@types/node': 20.12.11 '@types/node': 20.14.10
'@types/semver@7.5.8': {} '@types/semver@7.5.8': {}
@ -1849,17 +1665,14 @@ snapshots:
ansi-styles@6.2.1: {} ansi-styles@6.2.1: {}
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
archy@1.0.0: {} archy@1.0.0: {}
argparse@2.0.1: {} argparse@2.0.1: {}
array-union@2.1.0: {} array-union@2.1.0: {}
astravel@0.6.1: {}
astring@1.8.6: {} astring@1.8.6: {}
async-exit-hook@2.0.1: {} async-exit-hook@2.0.1: {}
@ -1879,8 +1692,6 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
binary-extensions@2.3.0: {}
brace-expansion@1.1.11: brace-expansion@1.1.11:
dependencies: dependencies:
balanced-match: 1.0.2 balanced-match: 1.0.2
@ -1910,18 +1721,6 @@ snapshots:
ansi-styles: 4.3.0 ansi-styles: 4.3.0
supports-color: 7.2.0 supports-color: 7.2.0
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
color-convert@2.0.1: color-convert@2.0.1:
dependencies: dependencies:
color-name: 1.1.4 color-name: 1.1.4
@ -1990,46 +1789,8 @@ snapshots:
entities@4.5.0: {} entities@4.5.0: {}
esbuild-plugin-copy@2.1.1(esbuild@0.20.2):
dependencies:
chalk: 4.1.2
chokidar: 3.6.0
esbuild: 0.20.2
fs-extra: 10.1.0
globby: 11.1.0
esbuild-plugin-time@1.0.0:
dependencies:
chalk: 4.1.2
esbuild-plugin-umd-wrapper@2.0.0: {} esbuild-plugin-umd-wrapper@2.0.0: {}
esbuild@0.20.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.20.2
'@esbuild/android-arm': 0.20.2
'@esbuild/android-arm64': 0.20.2
'@esbuild/android-x64': 0.20.2
'@esbuild/darwin-arm64': 0.20.2
'@esbuild/darwin-x64': 0.20.2
'@esbuild/freebsd-arm64': 0.20.2
'@esbuild/freebsd-x64': 0.20.2
'@esbuild/linux-arm': 0.20.2
'@esbuild/linux-arm64': 0.20.2
'@esbuild/linux-ia32': 0.20.2
'@esbuild/linux-loong64': 0.20.2
'@esbuild/linux-mips64el': 0.20.2
'@esbuild/linux-ppc64': 0.20.2
'@esbuild/linux-riscv64': 0.20.2
'@esbuild/linux-s390x': 0.20.2
'@esbuild/linux-x64': 0.20.2
'@esbuild/netbsd-x64': 0.20.2
'@esbuild/openbsd-x64': 0.20.2
'@esbuild/sunos-x64': 0.20.2
'@esbuild/win32-arm64': 0.20.2
'@esbuild/win32-ia32': 0.20.2
'@esbuild/win32-x64': 0.20.2
escape-html@1.0.3: {} escape-html@1.0.3: {}
escape-string-regexp@4.0.0: {} escape-string-regexp@4.0.0: {}
@ -2316,10 +2077,6 @@ snapshots:
ipaddr.js@2.2.0: {} ipaddr.js@2.2.0: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-core-module@2.13.1: is-core-module@2.13.1:
dependencies: dependencies:
hasown: 2.0.2 hasown: 2.0.2
@ -2401,6 +2158,10 @@ snapshots:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
magic-string@0.30.10:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
make-dir@3.1.0: make-dir@3.1.0:
dependencies: dependencies:
semver: 6.3.1 semver: 6.3.1
@ -2430,8 +2191,6 @@ snapshots:
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
normalize-path@3.0.0: {}
on-exit-leak-free@2.1.2: {} on-exit-leak-free@2.1.2: {}
once@1.4.0: once@1.4.0:
@ -2536,10 +2295,6 @@ snapshots:
process: 0.11.10 process: 0.11.10
string_decoder: 1.3.0 string_decoder: 1.3.0
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
real-require@0.2.0: {} real-require@0.2.0: {}
require-from-string@2.0.2: {} require-from-string@2.0.2: {}

35
rollup.config.js Normal file
View file

@ -0,0 +1,35 @@
import typescript from "rollup-plugin-typescript2";
import { join } from "node:path";
import fs from "node:fs"
import { fileURLToPath } from "node:url";
// check if its
const production = !process.env.ROLLUP_WATCH;
console.log(production)
fs.rmSync(join(fileURLToPath(new URL(".", import.meta.url)), "./dist"), { recursive: true, force: true })
const commonPlugins = () => [
typescript({
tsconfig: "tsconfig.json",
}),
]
export default {
plugins: commonPlugins(),
input: {
client: "./src/client/index.ts",
bundle: "./src/bundle/index.ts",
worker: "./src/worker/index.ts",
codecs: "./src/codecs/index.ts",
config: "./src/scramjet.config.ts"
},
output: {
entryFileNames: "scramjet.[name].js",
dir: "./dist",
format: "esm",
bundle: true,
minify: production,
sourcemap: true,
treeshake: "recommended",
},
};

74
server.js Normal file
View file

@ -0,0 +1,74 @@
// Dev server imports
import { createBareServer } from "@tomphttp/bare-server-node";
import { createServer } from "http";
import Fastify from "fastify";
import fastifyStatic from "@fastify/static";
import { join } from "node:path";
import fs from "node:fs"
import { fileURLToPath } from "node:url";
import { watch } from "rollup"
import { loadConfigFile } from "rollup/loadConfigFile"
//transports
import { baremuxPath } from "@mercuryworkshop/bare-mux/node"
import { epoxyPath } from "@mercuryworkshop/epoxy-transport"
import { libcurlPath } from "@mercuryworkshop/libcurl-transport"
import { bareModulePath } from "@mercuryworkshop/bare-as-module3"
let watcher = watch()
const bare = createBareServer("/bare/", {
logErrors: true
});
const fastify = Fastify({
serverFactory: (handler) => {
return createServer()
.on("request", (req, res) => {
if (bare.shouldRoute(req)) {
bare.routeRequest(req, res);
} else {
handler(req, res);
}
}).on("upgrade", (req, socket, head) => {
if (bare.shouldRoute(req)) {
bare.routeUpgrade(req, socket, head);
} else {
socket.end();
}
})
}
});
fastify.register(fastifyStatic, {
root: join(fileURLToPath(new URL(".", import.meta.url)), "./static"),
decorateReply: false
});
fastify.register(fastifyStatic, {
root: join(fileURLToPath(new URL(".", import.meta.url)), "./dist"),
prefix: "/dist/",
decorateReply: false
})
fastify.register(fastifyStatic, {
root: baremuxPath,
prefix: "/baremux/",
decorateReply: false
})
fastify.register(fastifyStatic, {
root: epoxyPath,
prefix: "/epoxy/",
decorateReply: false
})
fastify.register(fastifyStatic, {
root: libcurlPath,
prefix: "/libcurl/",
decorateReply: false
})
fastify.register(fastifyStatic, {
root: bareModulePath,
prefix: "/baremod/",
decorateReply: false
})
fastify.listen({
port: process.env.PORT || 1337
});

View file

@ -1,14 +1,14 @@
export { encodeUrl, decodeUrl } from "./rewriters/url"; export { encodeUrl, decodeUrl } from "./rewriters/url";
export { rewriteCss } from "./rewriters/css"; export { rewriteCss } from "./rewriters/css";
export { rewriteHtml, rewriteSrcset } from "./rewriters/html"; export { rewriteHtml, rewriteSrcset } from "./rewriters/html";
export { rewriteJs } from "./rewriters/js"; export { rewriteJs } from "./rewriters/js";
export { rewriteHeaders } from "./rewriters/headers"; export { rewriteHeaders } from "./rewriters/headers";
export function isScramjetFile(src: string) { export function isScramjetFile(src: string) {
let bool = false; let bool = false;
["codecs", "client", "bundle", "worker", "config"].forEach((file) => { ["codecs", "client", "bundle", "worker", "config"].forEach((file) => {
if (src === self.__scramjet$config[file]) bool = true; if (src === self.__scramjet$config[file]) bool = true;
}); });
return bool; return bool;
} }

View file

@ -1,35 +1,35 @@
// This CSS rewriter uses code from Meteor // This CSS rewriter uses code from Meteor
// You can find the original source code at https://github.com/MeteorProxy/Meteor // You can find the original source code at https://github.com/MeteorProxy/Meteor
import { encodeUrl } from "./url"; import { encodeUrl } from "./url";
export function rewriteCss(css: string, origin?: URL) { export function rewriteCss(css: string, origin?: URL) {
const regex = const regex =
/(@import\s+(?!url\())?\s*url\(\s*(['"]?)([^'")]+)\2\s*\)|@import\s+(['"])([^'"]+)\4/g /(@import\s+(?!url\())?\s*url\(\s*(['"]?)([^'")]+)\2\s*\)|@import\s+(['"])([^'"]+)\4/g
return css.replace( return css.replace(
regex, regex,
( (
match, match,
importStatement, importStatement,
urlQuote, urlQuote,
urlContent, urlContent,
importQuote, importQuote,
importContent importContent
) => { ) => {
const url = urlContent || importContent const url = urlContent || importContent
const encodedUrl = encodeUrl(url.trim(), origin) const encodedUrl = encodeUrl(url.trim(), origin)
if (importStatement) { if (importStatement) {
return `@import url(${urlQuote}${encodedUrl}${urlQuote})` return `@import url(${urlQuote}${encodedUrl}${urlQuote})`
} }
if (importQuote) { if (importQuote) {
return `@import ${importQuote}${encodedUrl}${importQuote}` return `@import ${importQuote}${encodedUrl}${importQuote}`
} }
return `url(${urlQuote}${encodedUrl}${urlQuote})` return `url(${urlQuote}${encodedUrl}${urlQuote})`
} }
) )
} }

View file

@ -1,53 +1,53 @@
import { encodeUrl } from "./url"; import { encodeUrl } from "./url";
import { BareHeaders } from "@mercuryworkshop/bare-mux"; import { BareHeaders } from "@mercuryworkshop/bare-mux";
const cspHeaders = [ const cspHeaders = [
"cross-origin-embedder-policy", "cross-origin-embedder-policy",
"cross-origin-opener-policy", "cross-origin-opener-policy",
"cross-origin-resource-policy", "cross-origin-resource-policy",
"content-security-policy", "content-security-policy",
"content-security-policy-report-only", "content-security-policy-report-only",
"expect-ct", "expect-ct",
"feature-policy", "feature-policy",
"origin-isolation", "origin-isolation",
"strict-transport-security", "strict-transport-security",
"upgrade-insecure-requests", "upgrade-insecure-requests",
"x-content-type-options", "x-content-type-options",
"x-download-options", "x-download-options",
"x-frame-options", "x-frame-options",
"x-permitted-cross-domain-policies", "x-permitted-cross-domain-policies",
"x-powered-by", "x-powered-by",
"x-xss-protection", "x-xss-protection",
// This needs to be emulated, but for right now it isn't that important of a feature to be worried about // This needs to be emulated, but for right now it isn't that important of a feature to be worried about
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
"clear-site-data" "clear-site-data"
]; ];
const urlHeaders = [ const urlHeaders = [
"location", "location",
"content-location", "content-location",
"referer" "referer"
]; ];
export function rewriteHeaders(rawHeaders: BareHeaders, origin?: URL) { export function rewriteHeaders(rawHeaders: BareHeaders, origin?: URL) {
const headers = {}; const headers = {};
for (const key in rawHeaders) { for (const key in rawHeaders) {
headers[key.toLowerCase()] = rawHeaders[key]; headers[key.toLowerCase()] = rawHeaders[key];
} }
cspHeaders.forEach((header) => { cspHeaders.forEach((header) => {
delete headers[header]; delete headers[header];
}); });
urlHeaders.forEach((header) => { urlHeaders.forEach((header) => {
if (headers[header]) if (headers[header])
headers[header] = encodeUrl(headers[header] as string, origin); headers[header] = encodeUrl(headers[header] as string, origin);
}); });
if (headers["link"]) { if (headers["link"]) {
headers["link"] = headers["link"].replace(/<(.*?)>/gi, (match) => encodeUrl(match, origin)); headers["link"] = headers["link"].replace(/<(.*?)>/gi, (match) => encodeUrl(match, origin));
} }
return headers; return headers;
} }

View file

@ -1,97 +1,97 @@
import { Parser } from "htmlparser2"; import { Parser } from "htmlparser2";
import { DomHandler, Element } from "domhandler"; import { DomHandler, Element } from "domhandler";
import { hasAttrib } from "domutils"; import { hasAttrib } from "domutils";
import render from "dom-serializer"; import render from "dom-serializer";
import { encodeUrl } from "./url"; import { encodeUrl } from "./url";
import { rewriteCss } from "./css"; import { rewriteCss } from "./css";
import { rewriteJs } from "./js"; import { rewriteJs } from "./js";
import { isScramjetFile } from "../"; import { isScramjetFile } from "../";
export function rewriteHtml(html: string, origin?: URL) { export function rewriteHtml(html: string, origin?: URL) {
const handler = new DomHandler((err, dom) => dom); const handler = new DomHandler((err, dom) => dom);
const parser = new Parser(handler); const parser = new Parser(handler);
parser.write(html); parser.write(html);
parser.end(); parser.end();
return render(traverseParsedHtml(handler.root, origin)); return render(traverseParsedHtml(handler.root, origin));
} }
// i need to add the attributes in during rewriting // i need to add the attributes in during rewriting
function traverseParsedHtml(node, origin?: URL) { function traverseParsedHtml(node, origin?: URL) {
/* csp attributes */ /* csp attributes */
for (const cspAttr of ["nonce", "integrity", "csp"]) { for (const cspAttr of ["nonce", "integrity", "csp"]) {
if (hasAttrib(node, cspAttr)) { if (hasAttrib(node, cspAttr)) {
node.attribs[`data-${cspAttr}`] = node.attribs[cspAttr]; node.attribs[`data-${cspAttr}`] = node.attribs[cspAttr];
delete node.attribs[cspAttr]; delete node.attribs[cspAttr];
} }
} }
/* url attributes */ /* url attributes */
for (const urlAttr of ["src", "href", "data", "action", "formaction"]) { for (const urlAttr of ["src", "href", "data", "action", "formaction"]) {
if (hasAttrib(node, urlAttr) && !isScramjetFile(node.attribs[urlAttr])) { if (hasAttrib(node, urlAttr) && !isScramjetFile(node.attribs[urlAttr])) {
const value = node.attribs[urlAttr]; const value = node.attribs[urlAttr];
node.attribs[`data-${urlAttr}`] = value; node.attribs[`data-${urlAttr}`] = value;
node.attribs[urlAttr] = encodeUrl(value, origin); node.attribs[urlAttr] = encodeUrl(value, origin);
} }
} }
/* other */ /* other */
for (const srcsetAttr of ["srcset", "imagesrcset"]) { for (const srcsetAttr of ["srcset", "imagesrcset"]) {
if (hasAttrib(node, srcsetAttr)) { if (hasAttrib(node, srcsetAttr)) {
const value = node.attribs[srcsetAttr]; const value = node.attribs[srcsetAttr];
node.attribs[`data-${srcsetAttr}`] = value; node.attribs[`data-${srcsetAttr}`] = value;
node.attribs[srcsetAttr] = rewriteSrcset(value, origin); node.attribs[srcsetAttr] = rewriteSrcset(value, origin);
} }
} }
if (hasAttrib(node, "srcdoc")) node.attribs.srcdoc = rewriteHtml(node.attribs.srcdoc, origin); if (hasAttrib(node, "srcdoc")) node.attribs.srcdoc = rewriteHtml(node.attribs.srcdoc, origin);
if (hasAttrib(node, "style")) node.attribs.style = rewriteCss(node.attribs.style, origin); if (hasAttrib(node, "style")) node.attribs.style = rewriteCss(node.attribs.style, origin);
if (node.name === "style" && node.children[0] !== undefined) node.children[0].data = rewriteCss(node.children[0].data, origin); if (node.name === "style" && node.children[0] !== undefined) node.children[0].data = rewriteCss(node.children[0].data, origin);
if (node.name === "script" && /(application|text)\/javascript|importmap|undefined/.test(node.attribs.type) && node.children[0] !== undefined) node.children[0].data = rewriteJs(node.children[0].data, origin); if (node.name === "script" && /(application|text)\/javascript|importmap|undefined/.test(node.attribs.type) && node.children[0] !== undefined) node.children[0].data = rewriteJs(node.children[0].data, origin);
if (node.name === "meta" && hasAttrib(node, "http-equiv")) { if (node.name === "meta" && hasAttrib(node, "http-equiv")) {
if (node.attribs["http-equiv"] === "content-security-policy") { if (node.attribs["http-equiv"] === "content-security-policy") {
node = {}; node = {};
} else if (node.attribs["http-equiv"] === "refresh" && node.attribs.content.includes("url")) { } else if (node.attribs["http-equiv"] === "refresh" && node.attribs.content.includes("url")) {
const contentArray = node.attribs.content.split("url="); const contentArray = node.attribs.content.split("url=");
contentArray[1] = encodeUrl(contentArray[1].trim(), origin); contentArray[1] = encodeUrl(contentArray[1].trim(), origin);
node.attribs.content = contentArray.join("url="); node.attribs.content = contentArray.join("url=");
} }
} }
if (node.name === "head") { if (node.name === "head") {
const scramjetScripts = []; const scramjetScripts = [];
["codecs", "config", "bundle", "client"].forEach((script) => { ["codecs", "config", "bundle", "client"].forEach((script) => {
scramjetScripts.push(new Element("script", { scramjetScripts.push(new Element("script", {
src: self.__scramjet$config[script], src: self.__scramjet$config[script],
type: "module" type: "module"
})); }));
}); });
node.children.unshift(...scramjetScripts); node.children.unshift(...scramjetScripts);
} }
if (node.childNodes) { if (node.childNodes) {
for (const childNode in node.childNodes) { for (const childNode in node.childNodes) {
node.childNodes[childNode] = traverseParsedHtml(node.childNodes[childNode], origin); node.childNodes[childNode] = traverseParsedHtml(node.childNodes[childNode], origin);
} }
} }
return node; return node;
} }
export function rewriteSrcset(srcset: string, origin?: URL) { export function rewriteSrcset(srcset: string, origin?: URL) {
const urls = srcset.split(/ [0-9]+x,? ?/g); const urls = srcset.split(/ [0-9]+x,? ?/g);
if (!urls) return ""; if (!urls) return "";
const sufixes = srcset.match(/ [0-9]+x,? ?/g); const sufixes = srcset.match(/ [0-9]+x,? ?/g);
if (!sufixes) return ""; if (!sufixes) return "";
const rewrittenUrls = urls.map((url, i) => { const rewrittenUrls = urls.map((url, i) => {
if (url && sufixes[i]) { if (url && sufixes[i]) {
return encodeUrl(url, origin) + sufixes[i]; return encodeUrl(url, origin) + sufixes[i];
} }
}); });
return rewrittenUrls.join(""); return rewrittenUrls.join("");
} }

View file

@ -1,49 +1,78 @@
import { parseModule } from "meriyah"; import { parseModule } from "meriyah";
import { generate } from "astring"; import { generate } from "astring";
import { encodeUrl } from "./url"; import { makeTraveler } from "astravel";
import { replace } from "estraverse"; import { encodeUrl } from "./url";
import * as ESTree from "estree";
// i am a cat. i like to be petted. i like to be fed. i like to be
// i am a cat. i like to be petted. i like to be fed. i like to be
// js rewiter is NOT finished
// js rewiter is NOT finished
// location
// window // location
// self // window
// globalThis // self
// this // globalThis
// top // this
// parent // top
// parent
export function rewriteJs(js: string, origin?: URL) {
try { export function rewriteJs(js: string, origin?: URL) {
const ast = parseModule(js); try {
const ast = parseModule(js, {
// const identifierList = [ module: true,
// "window", webcompat: true
// "self", });
// "globalThis",
// "parent", const identifierList = [
// "top", "window",
// "location", "self",
// "" "globalThis",
// ] "this",
"parent",
replace(ast, { "top",
enter: (node, parent) => { "location"
if (["ImportDeclaration", "ImportExpression", "ExportAllDeclaration", "ExportNamedDeclaration"].includes(node.type) && node.source) { ]
node.source.value = encodeUrl(node.source.value, origin);
} const customTraveler = makeTraveler({
ImportDeclaration: (node: ESTree.ImportDeclaration) => {
return node; node.source.value = encodeUrl(node.source.value as string, origin);
}, },
fallback: "iteration" ImportExpression: (node: ESTree.ImportExpression) => {
}) if (node.source.type === "Literal") {
node.source.value = encodeUrl(node.source.value as string, origin);
return generate(ast); } else if (node.source.type === "Identifier") {
} catch (err) { // this is for things that import something like
throw new Error(err); // const moduleName = "name";
} // await import(moduleName);
node.source.name = `__wrapImport(${node.source.name})`;
}
},
ExportAllDeclaration: (node: ESTree.ExportAllDeclaration) => {
node.source.value = encodeUrl(node.source.value as string, origin);
},
ExportNamedDeclaration: (node: ESTree.ExportNamedDeclaration) => {
// strings are Literals in ESTree syntax but these will always be strings
if (node.source) node.source.value = encodeUrl(node.source.value as string, origin);
},
// js rweriting notrdone
MemberExpression: (node: ESTree.MemberExpression) => {
if (node.object.type === "Identifier" && identifierList.includes(node.object.name)) {
node.object.name = "__" + node.object.name;
}
}
});
customTraveler.go(ast);
return generate(ast);
} catch {
console.log(js);
return js;
}
} }

View file

@ -1,37 +1,37 @@
import { rewriteJs } from "./js"; import { rewriteJs } from "./js";
function canParseUrl(url: string, origin?: URL) { function canParseUrl(url: string, origin?: URL) {
try { try {
new URL(url, origin); new URL(url, origin);
return true; return true;
} catch { } catch {
return false; return false;
} }
} }
// something is broken with this but i didn't debug it // something is broken with this but i didn't debug it
export function encodeUrl(url: string, origin?: URL) { export function encodeUrl(url: string, origin?: URL) {
if (!origin) { if (!origin) {
origin = new URL(self.__scramjet$config.codec.decode(location.href.slice((location.origin + self.__scramjet$config.prefix).length))); origin = new URL(self.__scramjet$config.codec.decode(location.href.slice((location.origin + self.__scramjet$config.prefix).length)));
} }
if (url.startsWith("javascript:")) { if (url.startsWith("javascript:")) {
return "javascript:" + rewriteJs(url.slice("javascript:".length)); return "javascript:" + rewriteJs(url.slice("javascript:".length));
} else if (/^(#|mailto|about|data)/.test(url)) { } else if (/^(#|mailto|about|data)/.test(url)) {
return url; return url;
} else if (canParseUrl(url, origin)) { } else if (canParseUrl(url, origin)) {
return location.origin + self.__scramjet$config.prefix + self.__scramjet$config.codec.encode(new URL(url, origin).href); return location.origin + self.__scramjet$config.prefix + self.__scramjet$config.codec.encode(new URL(url, origin).href);
} }
} }
// something is also broken with this but i didn't debug it // something is also broken with this but i didn't debug it
export function decodeUrl(url: string) { export function decodeUrl(url: string) {
if (/^(#|about|data|mailto|javascript)/.test(url)) { if (/^(#|about|data|mailto|javascript)/.test(url)) {
return url; return url;
} else if (canParseUrl(url)) { } else if (canParseUrl(url)) {
return self.__scramjet$config.codec.decode(url.slice((location.origin + self.__scramjet$config.prefix).length)) return self.__scramjet$config.codec.decode(url.slice((location.origin + self.__scramjet$config.prefix).length))
} else { } else {
return url; return url;
} }
} }

View file

@ -1,9 +1,9 @@
import { encodeUrl } from "../bundle"; import { encodeUrl } from "../bundle";
navigator.sendBeacon = new Proxy(navigator.sendBeacon, { navigator.sendBeacon = new Proxy(navigator.sendBeacon, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
argArray[0] = encodeUrl(argArray[0]); argArray[0] = encodeUrl(argArray[0]);
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });

View file

@ -1,26 +1,26 @@
import { rewriteCss } from "../bundle"; import { rewriteCss } from "../bundle";
const cssProperties = ["background", "background-image", "mask", "mask-image", "list-style", "list-style-image", "border-image", "border-image-source", "cursor"]; const cssProperties = ["background", "background-image", "mask", "mask-image", "list-style", "list-style-image", "border-image", "border-image-source", "cursor"];
const jsProperties = ["background", "backgroundImage", "mask", "maskImage", "listStyle", "listStyleImage", "borderImage", "borderImageSource", "cursor"]; const jsProperties = ["background", "backgroundImage", "mask", "maskImage", "listStyle", "listStyleImage", "borderImage", "borderImageSource", "cursor"];
CSSStyleDeclaration.prototype.setProperty = new Proxy(CSSStyleDeclaration.prototype.setProperty, { CSSStyleDeclaration.prototype.setProperty = new Proxy(CSSStyleDeclaration.prototype.setProperty, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (cssProperties.includes(argArray[0])) argArray[1] = rewriteCss(argArray[1]); if (cssProperties.includes(argArray[0])) argArray[1] = rewriteCss(argArray[1]);
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });
jsProperties.forEach((prop) => { jsProperties.forEach((prop) => {
const propDescriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, prop); const propDescriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, prop);
Object.defineProperty(CSSStyleDeclaration.prototype, prop, { Object.defineProperty(CSSStyleDeclaration.prototype, prop, {
get() { get() {
return propDescriptor.get.call(this); return propDescriptor.get.call(this);
}, },
set(v) { set(v) {
return propDescriptor.set.call(this, rewriteCss(v)); return propDescriptor.set.call(this, rewriteCss(v));
}, },
}) })
}); });

View file

@ -1,98 +1,98 @@
import { encodeUrl, rewriteCss, rewriteHtml, rewriteJs, rewriteSrcset } from "../bundle"; import { encodeUrl, rewriteCss, rewriteHtml, rewriteJs, rewriteSrcset } from "../bundle";
const attrObject = { const attrObject = {
"nonce": [HTMLElement], "nonce": [HTMLElement],
"integrity": [HTMLScriptElement, HTMLLinkElement], "integrity": [HTMLScriptElement, HTMLLinkElement],
"csp": [HTMLIFrameElement], "csp": [HTMLIFrameElement],
"src": [HTMLImageElement, HTMLMediaElement, HTMLIFrameElement, HTMLEmbedElement, HTMLScriptElement], "src": [HTMLImageElement, HTMLMediaElement, HTMLIFrameElement, HTMLEmbedElement, HTMLScriptElement],
"href": [HTMLAnchorElement, HTMLLinkElement], "href": [HTMLAnchorElement, HTMLLinkElement],
"data": [HTMLObjectElement], "data": [HTMLObjectElement],
"action": [HTMLFormElement], "action": [HTMLFormElement],
"formaction": [HTMLButtonElement, HTMLInputElement], "formaction": [HTMLButtonElement, HTMLInputElement],
"srcdoc": [HTMLIFrameElement], "srcdoc": [HTMLIFrameElement],
"srcset": [HTMLImageElement, HTMLSourceElement], "srcset": [HTMLImageElement, HTMLSourceElement],
"imagesrcset": [HTMLLinkElement] "imagesrcset": [HTMLLinkElement]
} }
const attrs = Object.keys(attrObject); const attrs = Object.keys(attrObject);
for (const attr of attrs) { for (const attr of attrs) {
for (const element of attrObject[attr]) { for (const element of attrObject[attr]) {
const descriptor = Object.getOwnPropertyDescriptor(element.prototype, attr); const descriptor = Object.getOwnPropertyDescriptor(element.prototype, attr);
Object.defineProperty(element.prototype, attr, { Object.defineProperty(element.prototype, attr, {
get() { get() {
return this.dataset[attr]; return this.dataset[attr];
}, },
set(value) { set(value) {
this.dataset[attr] = value; this.dataset[attr] = value;
if (/nonce|integrity|csp/.test(attr)) { if (/nonce|integrity|csp/.test(attr)) {
return; return;
} else if (/src|href|data|action|formaction/.test(attr)) { } else if (/src|href|data|action|formaction/.test(attr)) {
// @ts-expect-error // @ts-expect-error
if (value instanceof TrustedScriptURL) { if (value instanceof TrustedScriptURL) {
return; return;
} }
value = encodeUrl(value); value = encodeUrl(value);
} else if (attr === "srcdoc") { } else if (attr === "srcdoc") {
value = rewriteHtml(value); value = rewriteHtml(value);
} else if (/(image)?srcset/.test(attr)) { } else if (/(image)?srcset/.test(attr)) {
value = rewriteSrcset(value); value = rewriteSrcset(value);
} }
descriptor.set.call(this, value); descriptor.set.call(this, value);
}, },
}); });
} }
} }
Element.prototype.getAttribute = new Proxy(Element.prototype.getAttribute, { Element.prototype.getAttribute = new Proxy(Element.prototype.getAttribute, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (attrs.includes(argArray[0]) && thisArg.dataset[argArray[0]]) { if (attrs.includes(argArray[0]) && thisArg.dataset[argArray[0]]) {
return thisArg.dataset[argArray[0]]; return thisArg.dataset[argArray[0]];
} }
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });
Element.prototype.setAttribute = new Proxy(Element.prototype.setAttribute, { Element.prototype.setAttribute = new Proxy(Element.prototype.setAttribute, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (attrs.includes(argArray[0])) { if (attrs.includes(argArray[0])) {
thisArg.dataset[argArray[0]] = argArray[1]; thisArg.dataset[argArray[0]] = argArray[1];
if (/nonce|integrity|csp/.test(argArray[0])) { if (/nonce|integrity|csp/.test(argArray[0])) {
return; return;
} else if (/src|href|data|action|formaction/.test(argArray[0])) { } else if (/src|href|data|action|formaction/.test(argArray[0])) {
console.log(thisArg); console.log(thisArg);
argArray[1] = encodeUrl(argArray[1]); argArray[1] = encodeUrl(argArray[1]);
} else if (argArray[0] === "srcdoc") { } else if (argArray[0] === "srcdoc") {
argArray[1] = rewriteHtml(argArray[1]); argArray[1] = rewriteHtml(argArray[1]);
} else if (/(image)?srcset/.test(argArray[0])) { } else if (/(image)?srcset/.test(argArray[0])) {
argArray[1] = rewriteSrcset(argArray[1]); argArray[1] = rewriteSrcset(argArray[1]);
} else if (argArray[1] === "style") { } else if (argArray[1] === "style") {
argArray[1] = rewriteCss(argArray[1]); argArray[1] = rewriteCss(argArray[1]);
} }
} }
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });
const innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML"); const innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
Object.defineProperty(Element.prototype, "innerHTML", { Object.defineProperty(Element.prototype, "innerHTML", {
set(value) { set(value) {
// @ts-expect-error // @ts-expect-error
if (this instanceof HTMLScriptElement && !(value instanceof TrustedScript)) { if (this instanceof HTMLScriptElement && !(value instanceof TrustedScript)) {
value = rewriteJs(value); value = rewriteJs(value);
} else if (this instanceof HTMLStyleElement) { } else if (this instanceof HTMLStyleElement) {
value = rewriteCss(value); value = rewriteCss(value);
// @ts-expect-error // @ts-expect-error
} else if (!(value instanceof TrustedHTML)) { } else if (!(value instanceof TrustedHTML)) {
value = rewriteHtml(value); value = rewriteHtml(value);
} }
return innerHTML.set.call(this, value); return innerHTML.set.call(this, value);
}, },
}) })

1
src/client/history.ts Normal file
View file

@ -0,0 +1 @@
// forgot aobut this api

View file

@ -1,16 +1,16 @@
import "./native/eval.ts"; import "./native/eval.ts";
import "./location.ts"; import "./location.ts";
import "./trustedTypes.ts"; import "./trustedTypes.ts";
import "./requests/fetch.ts"; import "./requests/fetch.ts";
import "./requests/xmlhttprequest.ts"; import "./requests/xmlhttprequest.ts";
import "./requests/websocket.ts" import "./requests/websocket.ts"
import "./element.ts"; import "./element.ts";
import "./storage.ts"; import "./storage.ts";
import "./css.ts"; import "./css.ts";
import "./worker.ts"; import "./worker.ts";
declare global { declare global {
interface Window { interface Window {
__location: Location; __location: Location;
} }
} }

View file

@ -1,34 +1,34 @@
// @ts-nocheck // @ts-nocheck
import { encodeUrl, decodeUrl } from "../bundle"; import { encodeUrl, decodeUrl } from "../bundle";
function urlLocation() { function urlLocation() {
const loc = new URL(decodeUrl(location.href)); const loc = new URL(decodeUrl(location.href));
loc.assign = (url: string) => location.assign(encodeUrl(url)); loc.assign = (url: string) => location.assign(encodeUrl(url));
loc.reload = () => location.reload(); loc.reload = () => location.reload();
loc.replace = (url: string) => location.replace(encodeUrl(url)); loc.replace = (url: string) => location.replace(encodeUrl(url));
loc.toString = () => loc.href; loc.toString = () => loc.href;
return loc; return loc;
} }
export function LocationProxy() { export function LocationProxy() {
const loc = urlLocation(); const loc = urlLocation();
return new Proxy(window.location, { return new Proxy(window.location, {
get(target, prop) { get(target, prop) {
return loc[prop]; return loc[prop];
}, },
set(obj, prop, value) { set(obj, prop, value) {
if (prop === "href") { if (prop === "href") {
location.href = encodeUrl(value); location.href = encodeUrl(value);
} else { } else {
loc[prop] = value; loc[prop] = value;
} }
return true; return true;
} }
}) })
} }
window.__location = LocationProxy(); window.__location = LocationProxy();

View file

@ -1,28 +1,28 @@
import { rewriteJs } from "../../bundle"; import { rewriteJs } from "../../bundle";
const FunctionProxy = new Proxy(Function, { const FunctionProxy = new Proxy(Function, {
construct(target, argArray) { construct(target, argArray) {
if (argArray.length === 1) { if (argArray.length === 1) {
return Reflect.construct(target, rewriteJs(argArray[0])); return Reflect.construct(target, rewriteJs(argArray[0]));
} else { } else {
return Reflect.construct(target, rewriteJs(argArray[argArray.length - 1])) return Reflect.construct(target, rewriteJs(argArray[argArray.length - 1]))
} }
}, },
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (argArray.length === 1) { if (argArray.length === 1) {
return Reflect.apply(target, undefined, rewriteJs(argArray[0])); return Reflect.apply(target, undefined, rewriteJs(argArray[0]));
} else { } else {
return Reflect.apply(target, undefined, [...argArray.map((x, index) => index === argArray.length - 1), rewriteJs(argArray[argArray.length - 1])]) return Reflect.apply(target, undefined, [...argArray.map((x, index) => index === argArray.length - 1), rewriteJs(argArray[argArray.length - 1])])
} }
}, },
}); });
delete window.Function; delete window.Function;
window.Function = FunctionProxy; window.Function = FunctionProxy;
delete window.eval; delete window.eval;
// since the function proxy is already rewriting the js we can just reuse it for the eval proxy // since the function proxy is already rewriting the js we can just reuse it for the eval proxy
window.eval = (str: string) => window.Function(str); window.eval = (str: string) => window.Function(str);

View file

@ -1,35 +1,35 @@
// ts throws an error if you dont do window.fetch // ts throws an error if you dont do window.fetch
import { encodeUrl, rewriteHeaders } from "../../bundle"; import { encodeUrl, rewriteHeaders } from "../../bundle";
window.fetch = new Proxy(window.fetch, { window.fetch = new Proxy(window.fetch, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
argArray[0] = encodeUrl(argArray[0]); argArray[0] = encodeUrl(argArray[0]);
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });
Headers = new Proxy(Headers, { Headers = new Proxy(Headers, {
construct(target, argArray, newTarget) { construct(target, argArray, newTarget) {
argArray[0] = rewriteHeaders(argArray[0]); argArray[0] = rewriteHeaders(argArray[0]);
return Reflect.construct(target, argArray, newTarget); return Reflect.construct(target, argArray, newTarget);
}, },
}) })
Request = new Proxy(Request, { Request = new Proxy(Request, {
construct(target, argArray, newTarget) { construct(target, argArray, newTarget) {
if (typeof argArray[0] === "string") argArray[0] = encodeUrl(argArray[0]); if (typeof argArray[0] === "string") argArray[0] = encodeUrl(argArray[0]);
return Reflect.construct(target, argArray, newTarget); return Reflect.construct(target, argArray, newTarget);
}, },
}); });
Response.redirect = new Proxy(Response.redirect, { Response.redirect = new Proxy(Response.redirect, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
argArray[0] = encodeUrl(argArray[0]); argArray[0] = encodeUrl(argArray[0]);
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });

View file

@ -1,17 +1,16 @@
import { BareClient } from "@mercuryworkshop/bare-mux" import { BareClient } from "@mercuryworkshop/bare-mux"
const client = new BareClient() const client = new BareClient()
const RealWebSocket = WebSocket const RealWebSocket = WebSocket
WebSocket = new Proxy(WebSocket, { WebSocket = new Proxy(WebSocket, {
construct(_target, args) { construct(_target, args) {
return client.createWebSocket( return client.createWebSocket(
args[0], args[0],
args[1], args[1],
RealWebSocket, RealWebSocket,
{ {
"User-Agent": navigator.userAgent "User-Agent": navigator.userAgent
}, },
// @ts-expect-error ArrayBuffer.prototype
ArrayBuffer.prototype )
) }
}
}) })

View file

@ -1,20 +1,20 @@
import { encodeUrl, rewriteHeaders } from "../../bundle"; import { encodeUrl, rewriteHeaders } from "../../bundle";
XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open, { XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (argArray[1]) argArray[1] = encodeUrl(argArray[1]); if (argArray[1]) argArray[1] = encodeUrl(argArray[1]);
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });
XMLHttpRequest.prototype.setRequestHeader = new Proxy(XMLHttpRequest.prototype.setRequestHeader, { XMLHttpRequest.prototype.setRequestHeader = new Proxy(XMLHttpRequest.prototype.setRequestHeader, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
let headerObject = Object.fromEntries([argArray]); let headerObject = Object.fromEntries([argArray]);
headerObject = rewriteHeaders(headerObject); headerObject = rewriteHeaders(headerObject);
argArray = Object.entries(headerObject)[0]; argArray = Object.entries(headerObject)[0];
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}); });

View file

@ -1,68 +1,69 @@
import IDBMapSync from "@webreflection/idb-map/sync"; import IDBMapSync from "@webreflection/idb-map/sync";
const store = new IDBMapSync(window.__location.host, { const store = new IDBMapSync(window.__location.host, {
prefix: "Storage", prefix: "Storage",
durability: "relaxed" durability: "relaxed"
}); });
await store.sync(); await store.sync();
function storageProxy(scope: Storage): Storage { function storageProxy(scope: Storage): Storage {
return new Proxy(scope, { return new Proxy(scope, {
get(target, prop) { get(target, prop) {
switch (prop) { switch (prop) {
case "getItem": case "getItem":
return (key: string) => { return (key: string) => {
return store.get(key); return store.get(key);
} }
case "setItem": case "setItem":
return (key: string, value: string) => { return (key: string, value: string) => {
store.set(key, value); store.set(key, value);
store.sync(); store.sync();
} }
case "removeItem": case "removeItem":
return (key: string) => { return (key: string) => {
store.delete(key); store.delete(key);
store.sync(); store.sync();
} }
case "clear": case "clear":
return () => { return () => {
store.clear(); store.clear();
store.sync(); store.sync();
} }
case "key": case "key":
return (index: number) => { return (index: number) => {
store.keys()[index]; store.keys()[index];
} }
case "length": case "length":
return store.size; return store.size;
default: default:
return store.get(prop); return store.get(prop);
} }
}, },
set(target, prop, value) { //@ts-ignore
store.set(prop, value); set(target, prop, value) {
store.sync(); store.set(prop, value);
}, store.sync();
},
defineProperty(target, property, attributes) {
store.set(property as string, attributes.value); defineProperty(target, property, attributes) {
store.set(property as string, attributes.value);
return true;
}, return true;
}) },
} })
}
const localStorageProxy = storageProxy(window.localStorage);
const sessionStorageProxy = storageProxy(window.sessionStorage); const localStorageProxy = storageProxy(window.localStorage);
const sessionStorageProxy = storageProxy(window.sessionStorage);
delete window.localStorage;
delete window.sessionStorage; delete window.localStorage;
delete window.sessionStorage;
window.localStorage = localStorageProxy;
window.sessionStorage = sessionStorageProxy; window.localStorage = localStorageProxy;
window.sessionStorage = sessionStorageProxy;

View file

@ -1,32 +1,32 @@
import { rewriteHtml, rewriteJs, encodeUrl } from "../bundle"; import { rewriteHtml, rewriteJs, encodeUrl } from "../bundle";
// @ts-expect-error // @ts-expect-error
trustedTypes.createPolicy = new Proxy(trustedTypes.createPolicy, { trustedTypes.createPolicy = new Proxy(trustedTypes.createPolicy, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (argArray[1].createHTML) { if (argArray[1].createHTML) {
argArray[1].createHTML = new Proxy(argArray[1].createHTML, { argArray[1].createHTML = new Proxy(argArray[1].createHTML, {
apply(target1, thisArg1, argArray1) { apply(target1, thisArg1, argArray1) {
return rewriteHtml(target1(...argArray1)); return rewriteHtml(target1(...argArray1));
}, },
}); });
} }
if (argArray[1].createScript) { if (argArray[1].createScript) {
argArray[1].createScript = new Proxy(argArray[1].createScript, { argArray[1].createScript = new Proxy(argArray[1].createScript, {
apply(target1, thisArg1, argArray1) { apply(target1, thisArg1, argArray1) {
return rewriteJs(target1(...argArray1)); return rewriteJs(target1(...argArray1));
}, },
}); });
} }
if (argArray[1].createScriptURL) { if (argArray[1].createScriptURL) {
argArray[1].createScriptURL = new Proxy(argArray[1].createScriptURL, { argArray[1].createScriptURL = new Proxy(argArray[1].createScriptURL, {
apply(target1, thisArg1, argArray1) { apply(target1, thisArg1, argArray1) {
return encodeUrl(target1(...argArray1)); return encodeUrl(target1(...argArray1));
}, },
}) })
} }
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
}, },
}) })

1
src/client/window.ts Normal file
View file

@ -0,0 +1 @@
// the DAMN WINDOW PROXY

View file

@ -1,7 +1,7 @@
import { encodeUrl } from "../bundle"; import { encodeUrl } from "../bundle";
const RealWorker = Worker const RealWorker = Worker
Worker = new Proxy(Worker, { Worker = new Proxy(Worker, {
construct(_target, args) { construct(_target, args) {
return new RealWorker(encodeUrl(args[0]), args[1]) return new RealWorker(encodeUrl(args[0]), args[1])
} }
}) })

File diff suppressed because it is too large Load diff

View file

@ -1,82 +1,83 @@
import { enc, dec } from "./aes.ts"; import { enc, dec } from "./aes";
// for some reason eslint was parsing the type inside of the function params as a variable // for some reason eslint was parsing the type inside of the function params as a variable
export interface Codec { export interface Codec {
// eslint-disable-next-line // eslint-disable-next-line
encode: (str: string | undefined) => string; encode: (str: string | undefined) => string;
// eslint-disable-next-line // eslint-disable-next-line
decode: (str: string | undefined) => string; decode: (str: string | undefined) => string;
} }
const xor = { const xor = {
encode: (str: string | undefined, key: number = 2) => { encode: (str: string | undefined, key: number = 2) => {
if (!str) return str; if (!str) return str;
return encodeURIComponent(str.split("").map((e, i) => i % key ? String.fromCharCode(e.charCodeAt(0) ^ key) : e).join("")); return encodeURIComponent(str.split("").map((e, i) => i % key ? String.fromCharCode(e.charCodeAt(0) ^ key) : e).join(""));
}, },
decode: (str: string | undefined, key: number = 2) => { decode: (str: string | undefined, key: number = 2) => {
if (!str) return str; if (!str) return str;
return decodeURIComponent(str).split("").map((e, i) => i % key ? String.fromCharCode(e.charCodeAt(0) ^ key) : e).join(""); return decodeURIComponent(str).split("").map((e, i) => i % key ? String.fromCharCode(e.charCodeAt(0) ^ key) : e).join("");
} }
} }
const plain = { const plain = {
encode: (str: string | undefined) => { encode: (str: string | undefined) => {
if (!str) return str; if (!str) return str;
return encodeURIComponent(str); return encodeURIComponent(str);
}, },
decode: (str: string | undefined) => { decode: (str: string | undefined) => {
if (!str) return str; if (!str) return str;
return decodeURIComponent(str); return decodeURIComponent(str);
} }
} }
const aes = { /*
encode: (str: string | undefined) => { const aes = {
if (!str) return str; encode: (str: string | undefined) => {
if (!str) return str;
return encodeURIComponent(enc(str, "dynamic").substring(10));
}, return encodeURIComponent(enc(str, "dynamic").substring(10));
decode: (str: string | undefined) => { },
if (!str) return str; decode: (str: string | undefined) => {
if (!str) return str;
return dec("U2FsdGVkX1" + decodeURIComponent(str), "dynamic");
} return dec("U2FsdGVkX1" + decodeURIComponent(str), "dynamic");
} }
}
const none = { */
encode: (str: string | undefined) => str,
decode: (str: string | undefined) => str, const none = {
} encode: (str: string | undefined) => str,
decode: (str: string | undefined) => str,
const base64 = { }
encode: (str: string | undefined) => {
if (!str) return str; const base64 = {
encode: (str: string | undefined) => {
return decodeURIComponent(btoa(str)); if (!str) return str;
},
decode: (str: string | undefined) => { return decodeURIComponent(btoa(str));
if (!str) return str; },
decode: (str: string | undefined) => {
return atob(str); if (!str) return str;
}
} return atob(str);
}
declare global { }
interface Window {
__scramjet$codecs: { declare global {
none: Codec; interface Window {
plain: Codec; __scramjet$codecs: {
base64: Codec; none: Codec;
xor: Codec; plain: Codec;
aes: Codec; base64: Codec;
} xor: Codec;
} }
} }
}
self.__scramjet$codecs = {
none, plain, base64, xor, aes self.__scramjet$codecs = {
none, plain, base64, xor
} }

View file

@ -1,25 +1,25 @@
import { Codec } from "./codecs"; import { Codec } from "./codecs";
declare global { declare global {
interface Window { interface Window {
__scramjet$config: { __scramjet$config: {
prefix: string; prefix: string;
codec: Codec codec: Codec
config: string; config: string;
bundle: string; bundle: string;
worker: string; worker: string;
client: string; client: string;
codecs: string; codecs: string;
} }
} }
} }
self.__scramjet$config = { self.__scramjet$config = {
prefix: "/scramjet/", prefix: "/scramjet/",
codec: self.__scramjet$codecs.plain, codec: self.__scramjet$codecs.plain,
config: "/scramjet.config.js", config: "/scramjet.config.js",
bundle: "/scramjet.bundle.js", bundle: "/scramjet.bundle.js",
worker: "/scramjet.worker.js", worker: "/scramjet.worker.js",
client: "/scramjet.client.js", client: "/scramjet.client.js",
codecs: "/scramjet.codecs.js" codecs: "/scramjet.codecs.js"
} }

View file

@ -1,194 +1,194 @@
import { BareClient } from "@mercuryworkshop/bare-mux"; import { BareClient } from "@mercuryworkshop/bare-mux";
import { BareResponseFetch } from "@mercuryworkshop/bare-mux"; import { BareResponseFetch } from "@mercuryworkshop/bare-mux";
import { encodeUrl, decodeUrl, rewriteCss, rewriteHeaders, rewriteHtml, rewriteJs } from "../bundle"; import { encodeUrl, decodeUrl, rewriteCss, rewriteHeaders, rewriteHtml, rewriteJs } from "../bundle";
declare global { declare global {
interface Window { interface Window {
ScramjetServiceWorker; ScramjetServiceWorker;
} }
} }
export default class ScramjetServiceWorker { export default class ScramjetServiceWorker {
client: typeof BareClient.prototype; client: typeof BareClient.prototype;
config: typeof self.__scramjet$config; config: typeof self.__scramjet$config;
constructor(config = self.__scramjet$config) { constructor(config = self.__scramjet$config) {
this.client = new BareClient(); this.client = new BareClient();
if (!config.prefix) config.prefix = "/scramjet/"; if (!config.prefix) config.prefix = "/scramjet/";
this.config = config; this.config = config;
} }
route({ request }: FetchEvent) { route({ request }: FetchEvent) {
if (request.url.startsWith(location.origin + this.config.prefix)) return true; if (request.url.startsWith(location.origin + this.config.prefix)) return true;
else return false; else return false;
} }
async fetch({ request }: FetchEvent) { async fetch({ request }: FetchEvent) {
const urlParam = new URLSearchParams(new URL(request.url).search); const urlParam = new URLSearchParams(new URL(request.url).search);
if (urlParam.has("url")) { if (urlParam.has("url")) {
return Response.redirect(encodeUrl(urlParam.get("url"), new URL(urlParam.get("url")))) return Response.redirect(encodeUrl(urlParam.get("url"), new URL(urlParam.get("url"))))
} }
try { try {
const url = new URL(decodeUrl(request.url)); const url = new URL(decodeUrl(request.url));
const response: BareResponseFetch = await this.client.fetch(url, { const response: BareResponseFetch = await this.client.fetch(url, {
method: request.method, method: request.method,
body: request.body, body: request.body,
headers: request.headers, headers: request.headers,
credentials: "omit", credentials: "omit",
mode: request.mode === "cors" ? request.mode : "same-origin", mode: request.mode === "cors" ? request.mode : "same-origin",
cache: request.cache, cache: request.cache,
redirect: request.redirect, redirect: request.redirect,
}); });
let responseBody; let responseBody;
const responseHeaders = rewriteHeaders(response.rawHeaders, url); const responseHeaders = rewriteHeaders(response.rawHeaders, url);
if (response.body) { if (response.body) {
switch (request.destination) { switch (request.destination) {
case "iframe": case "iframe":
case "document": case "document":
responseBody = rewriteHtml(await response.text(), url); responseBody = rewriteHtml(await response.text(), url);
break; break;
case "script": case "script":
responseBody = rewriteJs(await response.text(), url); responseBody = rewriteJs(await response.text(), url);
break; break;
case "style": case "style":
responseBody = rewriteCss(await response.text(), url); responseBody = rewriteCss(await response.text(), url);
break; break;
case "sharedworker": case "sharedworker":
case "worker": case "worker":
break; break;
default: default:
responseBody = response.body; responseBody = response.body;
break; break;
} }
} }
// downloads // downloads
if (["document", "iframe"].includes(request.destination)) { if (["document", "iframe"].includes(request.destination)) {
const header = responseHeaders["content-disposition"]; const header = responseHeaders["content-disposition"];
// validate header and test for filename // validate header and test for filename
if (!/\s*?((inline|attachment);\s*?)filename=/i.test(header)) { if (!/\s*?((inline|attachment);\s*?)filename=/i.test(header)) {
// if filename= wasn"t specified then maybe the remote specified to download this as an attachment? // if filename= wasn"t specified then maybe the remote specified to download this as an attachment?
// if it"s invalid then we can still possibly test for the attachment/inline type // if it"s invalid then we can still possibly test for the attachment/inline type
const type = /^\s*?attachment/i.test(header) const type = /^\s*?attachment/i.test(header)
? "attachment" ? "attachment"
: "inline"; : "inline";
// set the filename // set the filename
const [filename] = new URL(response.finalURL).pathname const [filename] = new URL(response.finalURL).pathname
.split("/") .split("/")
.slice(-1); .slice(-1);
responseHeaders[ responseHeaders[
"content-disposition" "content-disposition"
] = `${type}; filename=${JSON.stringify(filename)}`; ] = `${type}; filename=${JSON.stringify(filename)}`;
} }
} }
if (responseHeaders["accept"] === "text/event-stream") { if (responseHeaders["accept"] === "text/event-stream") {
responseHeaders["content-type"] = "text/event-stream"; responseHeaders["content-type"] = "text/event-stream";
} }
if (crossOriginIsolated) { if (crossOriginIsolated) {
responseHeaders["Cross-Origin-Embedder-Policy"] = "require-corp"; responseHeaders["Cross-Origin-Embedder-Policy"] = "require-corp";
} }
return new Response(responseBody, { return new Response(responseBody, {
headers: responseHeaders as HeadersInit, headers: responseHeaders as HeadersInit,
status: response.status, status: response.status,
statusText: response.statusText statusText: response.statusText
}) })
} catch (err) { } catch (err) {
if (!["document", "iframe"].includes(request.destination)) if (!["document", "iframe"].includes(request.destination))
return new Response(undefined, { status: 500 }); return new Response(undefined, { status: 500 });
console.error(err); console.error(err);
return renderError(err, decodeUrl(request.url)); return renderError(err, decodeUrl(request.url));
} }
} }
} }
function errorTemplate( function errorTemplate(
trace: string, trace: string,
fetchedURL: string, fetchedURL: string,
) { ) {
// turn script into a data URI so we don"t have to escape any HTML values // turn script into a data URI so we don"t have to escape any HTML values
const script = ` const script = `
errorTrace.value = ${JSON.stringify(trace)}; errorTrace.value = ${JSON.stringify(trace)};
fetchedURL.textContent = ${JSON.stringify(fetchedURL)}; fetchedURL.textContent = ${JSON.stringify(fetchedURL)};
for (const node of document.querySelectorAll("#hostname")) node.textContent = ${JSON.stringify( for (const node of document.querySelectorAll("#hostname")) node.textContent = ${JSON.stringify(
location.hostname location.hostname
)}; )};
reload.addEventListener("click", () => location.reload()); reload.addEventListener("click", () => location.reload());
version.textContent = "0.0.1"; version.textContent = "0.0.1";
` `
return ( return (
`<!DOCTYPE html> `<!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Error</title> <title>Error</title>
<style> <style>
* { background-color: white } * { background-color: white }
</style> </style>
</head> </head>
<body> <body>
<h1 id="errorTitle">Error processing your request</h1> <h1 id="errorTitle">Error processing your request</h1>
<hr /> <hr />
<p>Failed to load <b id="fetchedURL"></b></p> <p>Failed to load <b id="fetchedURL"></b></p>
<p id="errorMessage">Internal Server Error</p> <p id="errorMessage">Internal Server Error</p>
<textarea id="errorTrace" cols="40" rows="10" readonly></textarea> <textarea id="errorTrace" cols="40" rows="10" readonly></textarea>
<p>Try:</p> <p>Try:</p>
<ul> <ul>
<li>Checking your internet connection</li> <li>Checking your internet connection</li>
<li>Verifying you entered the correct address</li> <li>Verifying you entered the correct address</li>
<li>Clearing the site data</li> <li>Clearing the site data</li>
<li>Contacting <b id="hostname"></b>"s administrator</li> <li>Contacting <b id="hostname"></b>"s administrator</li>
<li>Verify the server isn"t censored</li> <li>Verify the server isn"t censored</li>
</ul> </ul>
<p>If you"re the administrator of <b id="hostname"></b>, try:</p> <p>If you"re the administrator of <b id="hostname"></b>, try:</p>
<ul> <ul>
<li>Restarting your server</li> <li>Restarting your server</li>
<li>Updating Scramjet</li> <li>Updating Scramjet</li>
<li>Troubleshooting the error on the <a href="https://github.com/MercuryWorkshop/scramjet" target="_blank">GitHub repository</a></li> <li>Troubleshooting the error on the <a href="https://github.com/MercuryWorkshop/scramjet" target="_blank">GitHub repository</a></li>
</ul> </ul>
<button id="reload">Reload</button> <button id="reload">Reload</button>
<hr /> <hr />
<p><i>Scramjet v<span id="version"></span></i></p> <p><i>Scramjet v<span id="version"></span></i></p>
<script src="${ <script src="${
"data:application/javascript," + encodeURIComponent(script) "data:application/javascript," + encodeURIComponent(script)
}"></script> }"></script>
</body> </body>
</html> </html>
` `
); );
} }
/** /**
* *
* @param {unknown} err * @param {unknown} err
* @param {string} fetchedURL * @param {string} fetchedURL
*/ */
function renderError(err, fetchedURL) { function renderError(err, fetchedURL) {
const headers = { const headers = {
"content-type": "text/html", "content-type": "text/html",
}; };
if (crossOriginIsolated) { if (crossOriginIsolated) {
headers["Cross-Origin-Embedd'er-Policy"] = "require-corp"; headers["Cross-Origin-Embedd'er-Policy"] = "require-corp";
} }
return new Response( return new Response(
errorTemplate( errorTemplate(
String(err), String(err),
fetchedURL fetchedURL
), ),
{ {
status: 500, status: 500,
headers: headers headers: headers
} }
); );
} }

View file

@ -1,29 +1,29 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title> <title>Document</title>
<link rel="prefetch" href="./scramjet.worker.js"> <link rel="prefetch" href="/scramjet/scramjet.worker.js">
<link rel="prefetch" href="./scramjet.bundle.js"> <link rel="prefetch" href="/scramjet/scramjet.bundle.js">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&amp;family=Inter+Tight:ital,wght@0,100..900;1,100..900&amp;family=Inter:wght@100..900&amp;display=swap&amp;" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&amp;family=Inter+Tight:ital,wght@0,100..900;1,100..900&amp;family=Inter:wght@100..900&amp;display=swap&amp;" rel="stylesheet">
<style> <style>
body, html, #app { body, html, #app {
font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, sans-serif; font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
width:100vw; width:100vw;
height:100vh; height:100vh;
margin: 0; margin: 0;
padding: 0; padding: 0;
background-color:#121212; background-color:#121212;
overflow: hidden; overflow: hidden;
} }
</style> </style>
</head> </head>
<body> <body>
<script src="https://unpkg.com/dreamland"></script> <script src="https://unpkg.com/dreamland"></script>
<script src="./bare-mux.js" defer></script> <script src="/baremux/index.js" defer></script>
<script src="./ui.js" defer></script> <script src="ui.js" defer></script>
<script src="./scramjet.codecs.js"></script> <script src="/scramjet/scramjet.codecs.js"></script>
<script src="./scramjet.config.js"></script> <script src="/scramjet/scramjet.config.js"></script>
</body> </body>
</html> </html>

View file

@ -1,17 +1,17 @@
import ScramjetServiceWorker from "./scramjet.worker.js"; import ScramjetServiceWorker from "./scramjet.worker.js";
import "./scramjet.codecs.js"; import "./scramjet.codecs.js";
import "./scramjet.config.js"; import "./scramjet.config.js";
const scramjet = new ScramjetServiceWorker(); const scramjet = new ScramjetServiceWorker();
async function handleRequest(event) { async function handleRequest(event) {
if (scramjet.route(event)) { if (scramjet.route(event)) {
return scramjet.fetch(event); return scramjet.fetch(event);
} }
return fetch(event.request) return fetch(event.request)
} }
self.addEventListener("fetch", (event) => { self.addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event)); event.respondWith(handleRequest(event));
}); });

View file

@ -1,100 +1,100 @@
navigator.serviceWorker.register("./sw.js", { navigator.serviceWorker.register("./sw.js", {
scope: __scramjet$config.prefix, scope: __scramjet$config.prefix,
type: "module" type: "module"
}) })
const connection = new BareMux.BareMuxConnection("/bare-mux-worker.js") const connection = new BareMux.BareMuxConnection("/bare-mux-worker.js")
const flex = css`display: flex;`; const flex = css`display: flex;`;
const col = css`flex-direction: column;`; const col = css`flex-direction: column;`;
const store = $store({ const store = $store({
url: "https://google.com", url: "https://google.com",
wispurl: "wss://wisp.mercurywork.shop/", wispurl: "wss://wisp.mercurywork.shop/",
bareurl: (location.protocol === "https:" ? "https" : "http") + "://" + location.host + "/bare/", bareurl: (location.protocol === "https:" ? "https" : "http") + "://" + location.host + "/bare/",
}, { ident: "settings", backing: "localstorage", autosave: "auto" }); }, { ident: "settings", backing: "localstorage", autosave: "auto" });
connection.setTransport("/bare-client.js", [store.bareurl]) connection.setTransport("/baremod/index.mjs", [store.bareurl])
function App() { function App() {
this.urlencoded = ""; this.urlencoded = "";
this.css = ` this.css = `
width: 100%; width: 100%;
height: 100%; height: 100%;
color: #e0def4; color: #e0def4;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
input, input,
button { button {
font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont,
sans-serif; sans-serif;
} }
h1 { h1 {
font-family: "Inter Tight", "Inter", system-ui, -apple-system, BlinkMacSystemFont, font-family: "Inter Tight", "Inter", system-ui, -apple-system, BlinkMacSystemFont,
sans-serif; sans-serif;
margin-bottom: 0; margin-bottom: 0;
} }
iframe { iframe {
border: 4px solid #313131; border: 4px solid #313131;
background-color: #121212; background-color: #121212;
border-radius: 1rem; border-radius: 1rem;
margin: 2em; margin: 2em;
margin-top: 0.5em; margin-top: 0.5em;
width: calc(100% - 4em); width: calc(100% - 4em);
height: calc(100% - 8em); height: calc(100% - 8em);
} }
input.bar { input.bar {
border: none; border: none;
outline: none; outline: none;
color: #fff; color: #fff;
height: 2em; height: 2em;
width: 60%; width: 60%;
text-align: center; text-align: center;
border-radius: 0.75em; border-radius: 0.75em;
background-color: #313131; background-color: #313131;
padding: 0.45em; padding: 0.45em;
} }
.cfg * { .cfg * {
margin: 2px; margin: 2px;
} }
.buttons button { .buttons button {
border: 2px solid #4c8bf5; border: 2px solid #4c8bf5;
background-color: #313131; background-color: #313131;
border-radius: 0.75em; border-radius: 0.75em;
color: #fff; color: #fff;
padding: 0.45em; padding: 0.45em;
} }
.cfg input { .cfg input {
border: none; border: none;
background-color: #313131; background-color: #313131;
border-radius: 0.75em; border-radius: 0.75em;
color: #fff; color: #fff;
outline: none; outline: none;
padding: 0.45em; padding: 0.45em;
} }
`; `;
return html` return html`
<div> <div>
<h1>Percury Unblocker</h1> <h1>Percury Unblocker</h1>
<p>surf the unblocked and mostly buggy web</p> <p>surf the unblocked and mostly buggy web</p>
<div class=${`${flex} ${col} cfg`}> <div class=${`${flex} ${col} cfg`}>
<input bind:value=${use(store.wispurl)}></input> <input bind:value=${use(store.wispurl)}></input>
<input bind:value=${use(store.bareurl)}></input> <input bind:value=${use(store.bareurl)}></input>
<div class=${`${flex} buttons`}> <div class=${`${flex} buttons`}>
<button on:click=${() => connection.setTransport("/bare-client.js", [store.bareurl])}>use bare server 3</button> <button on:click=${() => connection.setTransport("/baremod/index.mjs", [store.bareurl])}>use bare server 3</button>
<button on:click=${() => connection.setTransport("/curl-client.js", [{ wisp: store.wispurl }])}>use libcurl.js</button> <button on:click=${() => connection.setTransport("/libcurl/index.mjs", [{ wisp: store.wispurl }])}>use libcurl.js</button>
<button on:click=${() => connection.setTransport("/epoxy-client.js", [{ wisp: store.wispurl }])}>use epoxy</button> <button on:click=${() => connection.setTransport("/epoxy/index.mjs", [{ wisp: store.wispurl }])}>use epoxy</button>
<button on:click=${() => window.open(this.urlencoded)}>open in fullscreen</button> <button on:click=${() => window.open(this.urlencoded)}>open in fullscreen</button>
</div> </div>
</div> </div>
<input class="bar" bind:value=${use(store.url)} on:input=${(e) => (store.url = e.target.value)} on:keyup=${(e) => e.keyCode == 13 && console.log(this.urlencoded = __scramjet$config.prefix + __scramjet$config.codec.encode(e.target.value))}></input> <input class="bar" bind:value=${use(store.url)} on:input=${(e) => (store.url = e.target.value)} on:keyup=${(e) => e.keyCode == 13 && console.log(this.urlencoded = __scramjet$config.prefix + __scramjet$config.codec.encode(e.target.value))}></input>
<iframe src=${use(this.urlencoded)}></iframe> <iframe src=${use(this.urlencoded)}></iframe>
</div> </div>
` `
} }
window.addEventListener("load", () => { window.addEventListener("load", () => {
document.body.appendChild(h(App)) document.body.appendChild(h(App))
}) })

View file

@ -1,11 +1,10 @@
{ {
"compilerOptions": { "compilerOptions": {
// "allowJs": true, // "allowJs": true,
"allowImportingTsExtensions": true, "rootDir": "./src",
"rootDir": "./src", "target": "ES2022",
"target": "ES2022", "moduleResolution": "Bundler",
"moduleResolution": "Bundler", "module": "ES2022",
"module": "ES2022", },
"noEmit": true "include": ["src"],
}
} }