strip down dependencies (css rewriting broken)

This commit is contained in:
Percs 2024-07-11 23:07:21 -05:00
parent eb501ecf1b
commit d5b332d3c4
10 changed files with 55 additions and 322 deletions

View file

@ -31,6 +31,7 @@ await build({
),
},
bundle: true,
treeShaking: true,
logLevel: 'info',
outdir: 'dist/',
});

64
package-lock.json generated
View file

@ -10,14 +10,13 @@
"license": "MIT",
"devDependencies": {
"@mercuryworkshop/bare-mux": "^2.0.1",
"astring": "^1.8.6",
"css-tree": "^2.3.1",
"esbuild": "^0.18.11",
"eslint": "^8.28.0",
"esotope-hammerhead": "^0.6.4",
"events": "^3.3.0",
"idb": "^7.1.1",
"meriyah": "^4.3.7",
"mime-db": "^1.52.0",
"parse5": "^7.1.2",
"prettier": "^2.8.0",
"rimraf": "^5.0.1",
@ -536,12 +535,6 @@
"node": ">=14"
}
},
"node_modules/@types/estree": {
"version": "0.0.46",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz",
"integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==",
"dev": true
},
"node_modules/acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@ -609,6 +602,16 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"node_modules/astring": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
"integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==",
"dev": true,
"license": "MIT",
"bin": {
"astring": "bin/astring"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -914,15 +917,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/esotope-hammerhead": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/esotope-hammerhead/-/esotope-hammerhead-0.6.4.tgz",
"integrity": "sha512-QY4HXqvjLSFGoGgHvm3H1QUMNcpwnUpGRBaVVFWE5uqbPQh9HSWcA1YD7KwwL/IrgerDwZn00z5dtYT9Ot/C/A==",
"dev": true,
"dependencies": {
"@types/estree": "0.0.46"
}
},
"node_modules/espree": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
@ -1421,15 +1415,6 @@
"node": ">=10.4.0"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -2317,12 +2302,6 @@
"dev": true,
"optional": true
},
"@types/estree": {
"version": "0.0.46",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz",
"integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==",
"dev": true
},
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@ -2369,6 +2348,12 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"astring": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
"integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==",
"dev": true
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -2601,15 +2586,6 @@
"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
"dev": true
},
"esotope-hammerhead": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/esotope-hammerhead/-/esotope-hammerhead-0.6.4.tgz",
"integrity": "sha512-QY4HXqvjLSFGoGgHvm3H1QUMNcpwnUpGRBaVVFWE5uqbPQh9HSWcA1YD7KwwL/IrgerDwZn00z5dtYT9Ot/C/A==",
"dev": true,
"requires": {
"@types/estree": "0.0.46"
}
},
"espree": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
@ -2980,12 +2956,6 @@
"integrity": "sha512-JAlSOUqFU/rmLy2CEdZO5hN5E5dyUj1f4AlRR4GCQMjfobvd5lcm9JLkrqq0MgVaLQ/Zur590A+0RyUZhj0b5A==",
"dev": true
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",

View file

@ -22,14 +22,13 @@
},
"devDependencies": {
"@mercuryworkshop/bare-mux": "^2.0.1",
"astring": "^1.8.6",
"css-tree": "^2.3.1",
"esbuild": "^0.18.11",
"eslint": "^8.28.0",
"esotope-hammerhead": "^0.6.4",
"events": "^3.3.0",
"idb": "^7.1.1",
"meriyah": "^4.3.7",
"mime-db": "^1.52.0",
"parse5": "^7.1.2",
"prettier": "^2.8.0",
"rimraf": "^5.0.1",

View file

@ -1,4 +1,4 @@
import { parse, walk, generate } from 'css-tree';
import EventEmitter from 'events';
class CSS extends EventEmitter {
@ -6,9 +6,6 @@ class CSS extends EventEmitter {
super();
this.ctx = ctx;
this.meta = ctx.meta;
this.parse = parse;
this.walk = walk;
this.generate = generate;
}
rewrite(str, options) {
return this.recast(str, options, 'rewrite');
@ -19,18 +16,8 @@ class CSS extends EventEmitter {
recast(str, options, type) {
if (!str) return str;
str = new String(str).toString();
try {
const ast = this.parse(str, {
...options,
parseCustomProperty: true,
});
this.walk(ast, (node) => {
this.emit(node.type, node, options, type);
});
return this.generate(ast);
} catch (e) {
return str;
}
// no rewriting rn cry ab it
return str;
}
}

View file

@ -3,7 +3,6 @@ import CSS from './css.js';
import JS from './js.js';
import setCookie from 'set-cookie-parser';
import { xor, base64, plain } from './codecs.js';
import * as mimeTypes from './mime.js';
import {
validateCookie,
db,
@ -23,7 +22,6 @@ import {
createHtmlInject,
createJsInject,
} from './rewrite.html.js';
import { importStyle, url } from './rewrite.css.js';
//import { call, destructureDeclaration, dynamicImport, getProperty, importDeclaration, setProperty, sourceMethods, wrapEval, wrapIdentifier } from './rewrite.script.js';
import {
dynamicImport,
@ -157,9 +155,6 @@ class Ultraviolet {
attributes(this);
text(this);
injectHead(this);
// CSS
url(this);
importStyle(this);
// JS
importDeclaration(this);
dynamicImport(this);
@ -187,7 +182,6 @@ class Ultraviolet {
return this.js.source.bind(this.js);
}
static codec = { xor, base64, plain };
static mime = mimeTypes;
static setCookie = setCookie;
static openDB = openDB;
static BareClient = BareClient;

View file

@ -1,6 +1,6 @@
import { parseScript } from 'meriyah';
// import { parse } from 'acorn-hammerhead';
import { generate } from 'esotope-hammerhead';
import { generate } from 'astring';
import EventEmitter from 'events';
class JS extends EventEmitter {

View file

@ -1,169 +0,0 @@
import db from 'mime-db';
const EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
const TEXT_TYPE_REGEXP = /^text\//i;
const extensions = Object.create(null);
const types = Object.create(null);
const charsets = { lookup: charset };
// Populate the extensions/types maps
populateMaps(extensions, types);
/**
* Get the default charset for a MIME type.
*
* @param {string} type
* @return {boolean|string}
*/
function charset(type) {
if (!type || typeof type !== 'string') {
return false;
}
// TODO: use media-typer
const match = EXTRACT_TYPE_REGEXP.exec(type);
const mime = match && db[match[1].toLowerCase()];
if (mime && mime.charset) {
return mime.charset;
}
// default text/* to utf-8
if (match && TEXT_TYPE_REGEXP.test(match[1])) {
return 'UTF-8';
}
return false;
}
/**
* Create a full Content-Type header given a MIME type or extension.
*
* @param {string} str
* @return {boolean|string}
*/
function contentType(str) {
// TODO: should this even be in this module?
if (!str || typeof str !== 'string') {
return false;
}
let mime = str.indexOf('/') === -1 ? lookup(str) : str;
if (!mime) {
return false;
}
// TODO: use content-type or other module
if (mime.indexOf('charset') === -1) {
const detected = charset(mime);
if (detected) mime += '; charset=' + detected.toLowerCase();
}
return mime;
}
/**
* Get the default extension for a MIME type.
*
* @param {string} type
* @return {boolean|string}
*/
function extension(type) {
if (!type || typeof type !== 'string') {
return false;
}
// TODO: use media-typer
const match = EXTRACT_TYPE_REGEXP.exec(type);
// get extensions
const exts = match && extensions[match[1].toLowerCase()];
if (!exts || !exts.length) {
return false;
}
return exts[0];
}
/**
* Lookup the MIME type for a file path/extension.
*
* @param {string} path
* @return {boolean|string}
*/
function lookup(path) {
if (!path || typeof path !== 'string') {
return false;
}
// get the extension ("ext" or ".ext" or full path)
const extension = extname('x.' + path)
.toLowerCase()
.slice(1);
if (!extension) {
return false;
}
return types[extension] || false;
}
/**
* Populate the extensions and types maps.
* @private
*/
function populateMaps(extensions, types) {
// source preference (least -> most)
const preference = ['nginx', 'apache', undefined, 'iana'];
for (const type in db) {
const mime = db[type];
const exts = mime.extensions;
if (!exts || !exts.length) {
return;
}
// mime -> extensions
extensions[type] = exts;
// extension -> mime
for (let i = 0; i < exts.length; i++) {
const extension = exts[i];
if (types[extension]) {
const from = preference.indexOf(db[types[extension]].source);
const to = preference.indexOf(mime.source);
if (
types[extension] !== 'application/octet-stream' &&
(from > to ||
(from === to &&
types[extension].substr(0, 12) === 'application/'))
) {
// skip the remapping
continue;
}
}
// set the extension -> mime
types[extension] = type;
}
}
}
function extname(path = '') {
if (!path.includes('.')) return '';
const map = path.split('.');
return '.' + map[map.length - 1];
}
export { charset, charsets, contentType, extension, lookup };

View file

@ -1,37 +0,0 @@
/**
* @typedef {import('./index').default} Ultraviolet
*/
/**
*
* @param {Ultraviolet} ctx
*/
function url(ctx) {
const { css } = ctx;
css.on('Url', (node, data, type) => {
node.value =
type === 'rewrite'
? ctx.rewriteUrl(node.value)
: ctx.sourceUrl(node.value);
});
}
/**
*
* @param {Ultraviolet} ctx
*/
function importStyle(ctx) {
const { css } = ctx;
css.on('Atrule', (node, data, type) => {
if (node.name !== 'import') return false;
const { data: url } = node.prelude.children.head;
// Already handling Url's
if (url.type === 'Url') return false;
url.value =
type === 'rewrite'
? ctx.rewriteUrl(url.value)
: ctx.sourceUrl(url.value);
});
}
export { url, importStyle };

View file

@ -1,5 +1,3 @@
import { Syntax } from 'esotope-hammerhead';
/**
* @typedef {import('./index').default} Ultraviolet
*/
@ -108,7 +106,7 @@ function property(ctx) {
!node.computed &&
node.property.name === '__uv$setSource' &&
type === 'source' &&
node.parent.type === Syntax.CallExpression
node.parent.type === "CallExpression"
) {
const { parent, property } = node;
data.changes.push({
@ -137,57 +135,57 @@ function identifier(ctx) {
const { parent } = node;
if (!['location', 'eval', 'parent', 'top'].includes(node.name))
return false;
if (parent.type === Syntax.VariableDeclarator && parent.id === node)
if (parent.type === "VariableDeclarator" && parent.id === node)
return false;
if (
(parent.type === Syntax.AssignmentExpression ||
parent.type === Syntax.AssignmentPattern) &&
(parent.type === "AssignmentExpression" ||
parent.type === "AssignmentPattern") &&
parent.left === node
)
return false;
if (
(parent.type === Syntax.FunctionExpression ||
parent.type === Syntax.FunctionDeclaration) &&
(parent.type === "FunctionExpression" ||
parent.type === "FunctionDeclaration") &&
parent.id === node
)
return false;
if (
parent.type === Syntax.MemberExpression &&
parent.type === "MemberExpression" &&
parent.property === node &&
!parent.computed
)
return false;
if (
node.name === 'eval' &&
parent.type === Syntax.CallExpression &&
parent.type === "CallExpression" &&
parent.callee === node
)
return false;
if (parent.type === Syntax.Property && parent.key === node)
if (parent.type === "Property" && parent.key === node)
return false;
if (
parent.type === Syntax.Property &&
parent.type === "Property" &&
parent.value === node &&
parent.shorthand
)
return false;
if (
parent.type === Syntax.UpdateExpression &&
parent.type === "UpdateExpression" &&
(parent.operator === '++' || parent.operator === '--')
)
return false;
if (
(parent.type === Syntax.FunctionExpression ||
parent.type === Syntax.FunctionDeclaration ||
parent.type === Syntax.ArrowFunctionExpression) &&
(parent.type === "FunctionExpression" ||
parent.type === "FunctionDeclaration" ||
parent.type === "ArrowFunctionExpression") &&
parent.params.indexOf(node) !== -1
)
return false;
if (parent.type === Syntax.MethodDefinition) return false;
if (parent.type === Syntax.ClassDeclaration) return false;
if (parent.type === Syntax.RestElement) return false;
if (parent.type === Syntax.ExportSpecifier) return false;
if (parent.type === Syntax.ImportSpecifier) return false;
if (parent.type === "MethodDefinition") return false;
if (parent.type === "ClassDeclaration") return false;
if (parent.type === "RestElement") return false;
if (parent.type === "ExportSpecifier") return false;
if (parent.type === "ImportSpecifier") return false;
data.changes.push({
start: node.start,
@ -232,12 +230,12 @@ function wrapEval(ctx) {
*/
function importDeclaration(ctx) {
const { js } = ctx;
js.on(Syntax.Literal, (node, data, type) => {
js.on("Literal", (node, data, type) => {
if (
!(
(node.parent.type === Syntax.ImportDeclaration ||
node.parent.type === Syntax.ExportAllDeclaration ||
node.parent.type === Syntax.ExportNamedDeclaration) &&
(node.parent.type === "ImportDeclaration" ||
node.parent.type === "ExportAllDeclaration" ||
node.parent.type === "ExportNamedDeclaration") &&
node.parent.source === node
)
)
@ -260,7 +258,7 @@ function importDeclaration(ctx) {
*/
function dynamicImport(ctx) {
const { js } = ctx;
js.on(Syntax.ImportExpression, (node, data, type) => {
js.on("ImportExpression", (node, data, type) => {
if (type !== 'rewrite') return false;
data.changes.push({
// pass script URL to dynamicImport
@ -294,7 +292,7 @@ function unwrap(ctx) {
{
if (
!node.arguments ||
node.parent.type !== Syntax.MemberExpression ||
node.parent.type !== "MemberExpression" ||
node.parent.property !== node
)
return false;
@ -351,9 +349,9 @@ function unwrap(ctx) {
}
function isWrapped(node) {
if (node.type !== Syntax.MemberExpression) return false;
if (node.type !== "MemberExpression") return false;
if (node.property.name === 'rewrite' && isWrapped(node.object)) return true;
if (node.object.type !== Syntax.Identifier || node.object.name !== '__uv')
if (node.object.type !== "Identifier" || node.object.name !== '__uv')
return false;
if (!['js', '$get', '$wrap', 'rewriteUrl'].includes(node.property.name))
return false;

View file

@ -236,12 +236,8 @@ class UVServiceWorker extends Ultraviolet.EventEmitter {
break;
case 'iframe':
case 'document':
if (
isHtml(
ultraviolet.meta.url,
responseCtx.headers['content-type'] || ''
)
) {
console.log(responseCtx.headers["content-type"])
if (responseCtx.headers["content-type"].startsWith("text/html")) {
responseCtx.body = ultraviolet.rewriteHtml(
await response.text(),
{
@ -261,6 +257,9 @@ class UVServiceWorker extends Ultraviolet.EventEmitter {
}
);
}
break;
default:
break;
}
}
@ -356,15 +355,6 @@ class RequestContext {
}
}
function isHtml(url, contentType = '') {
return (
(
Ultraviolet.mime.contentType(contentType || url.pathname) ||
'text/html'
).split(';')[0] === 'text/html'
);
}
class HookEvent {
#intercepted;
#returnValue;