wu-framework 1.1.15 → 1.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -20
- package/dist/wu-framework.cjs.js +1 -1
- package/dist/wu-framework.cjs.js.map +1 -1
- package/dist/wu-framework.dev.js +15511 -15146
- package/dist/wu-framework.dev.js.map +1 -1
- package/dist/wu-framework.esm.js +1 -1
- package/dist/wu-framework.esm.js.map +1 -1
- package/dist/wu-framework.umd.js +1 -1
- package/dist/wu-framework.umd.js.map +1 -1
- package/package.json +166 -161
- package/src/adapters/angular/ai.js +30 -30
- package/src/adapters/angular/index.d.ts +154 -154
- package/src/adapters/angular/index.js +932 -932
- package/src/adapters/angular.d.ts +3 -3
- package/src/adapters/angular.js +3 -3
- package/src/adapters/index.js +168 -168
- package/src/adapters/lit/ai.js +20 -20
- package/src/adapters/lit/index.d.ts +120 -120
- package/src/adapters/lit/index.js +721 -721
- package/src/adapters/lit.d.ts +3 -3
- package/src/adapters/lit.js +3 -3
- package/src/adapters/preact/ai.js +33 -33
- package/src/adapters/preact/index.d.ts +108 -108
- package/src/adapters/preact/index.js +661 -661
- package/src/adapters/preact.d.ts +3 -3
- package/src/adapters/preact.js +3 -3
- package/src/adapters/react/index.js +48 -54
- package/src/adapters/react.d.ts +3 -3
- package/src/adapters/react.js +3 -3
- package/src/adapters/shared.js +64 -64
- package/src/adapters/solid/ai.js +32 -32
- package/src/adapters/solid/index.d.ts +101 -101
- package/src/adapters/solid/index.js +586 -586
- package/src/adapters/solid.d.ts +3 -3
- package/src/adapters/solid.js +3 -3
- package/src/adapters/svelte/ai.js +31 -31
- package/src/adapters/svelte/index.d.ts +166 -166
- package/src/adapters/svelte/index.js +798 -798
- package/src/adapters/svelte.d.ts +3 -3
- package/src/adapters/svelte.js +3 -3
- package/src/adapters/vanilla/ai.js +30 -30
- package/src/adapters/vanilla/index.d.ts +179 -179
- package/src/adapters/vanilla/index.js +785 -785
- package/src/adapters/vanilla.d.ts +3 -3
- package/src/adapters/vanilla.js +3 -3
- package/src/adapters/vue/ai.js +52 -52
- package/src/adapters/vue/index.d.ts +299 -299
- package/src/adapters/vue/index.js +610 -610
- package/src/adapters/vue.d.ts +3 -3
- package/src/adapters/vue.js +3 -3
- package/src/ai/wu-ai-actions.js +261 -261
- package/src/ai/wu-ai-agent.js +546 -546
- package/src/ai/wu-ai-browser-primitives.js +354 -354
- package/src/ai/wu-ai-browser.js +380 -380
- package/src/ai/wu-ai-context.js +332 -332
- package/src/ai/wu-ai-conversation.js +613 -613
- package/src/ai/wu-ai-orchestrate.js +1021 -1021
- package/src/ai/wu-ai-permissions.js +381 -381
- package/src/ai/wu-ai-provider.js +700 -700
- package/src/ai/wu-ai-schema.js +225 -225
- package/src/ai/wu-ai-triggers.js +396 -396
- package/src/ai/wu-ai.js +804 -804
- package/src/core/wu-app.js +236 -236
- package/src/core/wu-cache.js +498 -477
- package/src/core/wu-core.js +1412 -1398
- package/src/core/wu-error-boundary.js +396 -382
- package/src/core/wu-event-bus.js +390 -348
- package/src/core/wu-hooks.js +350 -350
- package/src/core/wu-html-parser.js +199 -190
- package/src/core/wu-iframe-sandbox.js +328 -328
- package/src/core/wu-loader.js +385 -273
- package/src/core/wu-logger.js +142 -134
- package/src/core/wu-manifest.js +532 -509
- package/src/core/wu-mcp-bridge.js +432 -432
- package/src/core/wu-overrides.js +510 -510
- package/src/core/wu-performance.js +228 -228
- package/src/core/wu-plugin.js +401 -348
- package/src/core/wu-prefetch.js +414 -414
- package/src/core/wu-proxy-sandbox.js +477 -476
- package/src/core/wu-sandbox.js +779 -779
- package/src/core/wu-script-executor.js +161 -113
- package/src/core/wu-snapshot-sandbox.js +227 -227
- package/src/core/wu-store.js +13 -3
- package/src/core/wu-strategies.js +256 -256
- package/src/core/wu-style-bridge.js +477 -477
- package/src/index.d.ts +317 -0
- package/src/index.js +234 -224
- package/src/utils/dependency-resolver.js +327 -327
|
@@ -1,113 +1,161 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WU-SCRIPT-EXECUTOR: Execute scripts inside a Proxy sandbox.
|
|
3
|
-
*
|
|
4
|
-
* Two isolation levels:
|
|
5
|
-
* - strictGlobal: true → with(proxy) { code } — all global access goes through proxy
|
|
6
|
-
* - strictGlobal: false → (function(window){ code })(proxy) — only explicit window.xxx
|
|
7
|
-
*
|
|
8
|
-
* This is what makes the sandbox REAL instead of decorative.
|
|
9
|
-
* Without this, import() runs code in global scope and the proxy is just a cleanup tracker.
|
|
10
|
-
* With this, code receives the proxy as "window" and every setTimeout, addEventListener,
|
|
11
|
-
* document.querySelector, localStorage access goes through the proxy's traps.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { logger } from './wu-logger.js';
|
|
15
|
-
|
|
16
|
-
export class WuScriptExecutor {
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* WU-SCRIPT-EXECUTOR: Execute scripts inside a Proxy sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Two isolation levels:
|
|
5
|
+
* - strictGlobal: true → with(proxy) { code } — all global access goes through proxy
|
|
6
|
+
* - strictGlobal: false → (function(window){ code })(proxy) — only explicit window.xxx
|
|
7
|
+
*
|
|
8
|
+
* This is what makes the sandbox REAL instead of decorative.
|
|
9
|
+
* Without this, import() runs code in global scope and the proxy is just a cleanup tracker.
|
|
10
|
+
* With this, code receives the proxy as "window" and every setTimeout, addEventListener,
|
|
11
|
+
* document.querySelector, localStorage access goes through the proxy's traps.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { logger } from './wu-logger.js';
|
|
15
|
+
|
|
16
|
+
export class WuScriptExecutor {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Dangerous patterns that indicate prototype pollution, sandbox escape,
|
|
20
|
+
* or direct access to sensitive APIs. Each entry is a regex paired with
|
|
21
|
+
* a human-readable label used in error messages.
|
|
22
|
+
*
|
|
23
|
+
* This is a tripwire, not a full parser. It catches the most common
|
|
24
|
+
* attack vectors without the overhead of AST analysis.
|
|
25
|
+
*/
|
|
26
|
+
static DANGEROUS_PATTERNS = [
|
|
27
|
+
// Prototype pollution vectors
|
|
28
|
+
{ pattern: /constructor\s*\[\s*['"`]constructor['"`]\s*\]/, label: 'constructor chain access (sandbox escape)' },
|
|
29
|
+
{ pattern: /__proto__/, label: '__proto__ access (prototype pollution)' },
|
|
30
|
+
|
|
31
|
+
// Sandbox escape via proxy introspection
|
|
32
|
+
{ pattern: /Object\s*\.\s*getPrototypeOf\s*\(\s*proxy\s*\)/, label: 'Object.getPrototypeOf(proxy) (sandbox escape)' },
|
|
33
|
+
|
|
34
|
+
// Dynamic code generation that bypasses the sandbox
|
|
35
|
+
{ pattern: /Function\s*\(\s*['"`]/, label: 'Function() constructor (dynamic code generation)' },
|
|
36
|
+
{ pattern: /\beval\s*\(/, label: 'eval() (dynamic code execution)' },
|
|
37
|
+
|
|
38
|
+
// Dynamic import escapes the sandbox entirely (runs in global scope)
|
|
39
|
+
{ pattern: /\bimport\s*\(/, label: 'import() (dynamic import escapes sandbox)' },
|
|
40
|
+
|
|
41
|
+
// Direct cookie access (should go through proxy traps, not raw document)
|
|
42
|
+
{ pattern: /document\s*\.\s*cookie/, label: 'document.cookie (direct cookie access)' },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validate script text against known dangerous patterns before execution.
|
|
47
|
+
* Throws if any pattern matches. This is intentionally lightweight --
|
|
48
|
+
* pattern detection only, not a full parse.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} scriptText - The raw script to validate
|
|
51
|
+
* @param {string} appName - App identifier (for error context)
|
|
52
|
+
* @throws {Error} If a dangerous pattern is detected
|
|
53
|
+
*/
|
|
54
|
+
_validateScript(scriptText, appName) {
|
|
55
|
+
for (const { pattern, label } of WuScriptExecutor.DANGEROUS_PATTERNS) {
|
|
56
|
+
if (pattern.test(scriptText)) {
|
|
57
|
+
const msg = `[ScriptExecutor] Blocked dangerous pattern in "${appName}": ${label}`;
|
|
58
|
+
logger.wuError(msg);
|
|
59
|
+
throw new Error(msg);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Execute a script string inside the proxy sandbox.
|
|
66
|
+
*
|
|
67
|
+
* @param {string} scriptText - JavaScript code to execute
|
|
68
|
+
* @param {string} appName - App identifier (for logging)
|
|
69
|
+
* @param {Proxy} proxy - The activated proxy sandbox
|
|
70
|
+
* @param {Object} [options]
|
|
71
|
+
* @param {boolean} [options.strictGlobal=true] - Use with(proxy) for maximum isolation
|
|
72
|
+
* @param {string} [options.sourceUrl=''] - Source URL for devtools (//# sourceURL)
|
|
73
|
+
* @returns {*} Return value of the executed code
|
|
74
|
+
*/
|
|
75
|
+
execute(scriptText, appName, proxy, options = {}) {
|
|
76
|
+
const { strictGlobal = true, sourceUrl = '' } = options;
|
|
77
|
+
|
|
78
|
+
if (!scriptText || !scriptText.trim()) return;
|
|
79
|
+
|
|
80
|
+
this._validateScript(scriptText, appName);
|
|
81
|
+
|
|
82
|
+
const sourceComment = sourceUrl ? `\n//# sourceURL=wu-sandbox:///${appName}/${sourceUrl}\n` : '';
|
|
83
|
+
|
|
84
|
+
let wrappedCode;
|
|
85
|
+
|
|
86
|
+
if (strictGlobal) {
|
|
87
|
+
// MAXIMUM ISOLATION
|
|
88
|
+
// with(window) makes ALL unqualified identifiers (setTimeout, fetch, document, etc.)
|
|
89
|
+
// resolve through the proxy's has/get traps, not the real window.
|
|
90
|
+
// Note: 'use strict' inside the with block becomes a no-op string expression,
|
|
91
|
+
// so bundled code with strict mode still works.
|
|
92
|
+
wrappedCode = `;(function(window, self, globalThis, top, parent) {
|
|
93
|
+
with(window) {
|
|
94
|
+
;${scriptText}${sourceComment}
|
|
95
|
+
}
|
|
96
|
+
}).call(proxy, proxy, proxy, proxy, proxy, proxy);`;
|
|
97
|
+
} else {
|
|
98
|
+
// IIFE ONLY — only explicit window.xxx goes through proxy
|
|
99
|
+
wrappedCode = `;(function(window, self, globalThis, top, parent) {
|
|
100
|
+
;${scriptText}${sourceComment}
|
|
101
|
+
}).call(proxy, proxy, proxy, proxy, proxy, proxy);`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// new Function('proxy', code) creates a function with 'proxy' as the single param.
|
|
106
|
+
// This avoids polluting scope — the only bridge to the sandbox is the proxy argument.
|
|
107
|
+
const fn = new Function('proxy', wrappedCode);
|
|
108
|
+
return fn(proxy);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// If strictGlobal failed (rare edge case with with-statement), retry without it
|
|
111
|
+
if (strictGlobal) {
|
|
112
|
+
logger.wuWarn(`[ScriptExecutor] strictGlobal failed for ${appName}, retrying without with(): ${error.message}`);
|
|
113
|
+
return this.execute(scriptText, appName, proxy, { ...options, strictGlobal: false });
|
|
114
|
+
}
|
|
115
|
+
logger.wuError(`[ScriptExecutor] Execution failed for ${appName}:`, error);
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Fetch script content from a URL.
|
|
122
|
+
* @param {string} url - Script URL
|
|
123
|
+
* @returns {Promise<string>} Script text
|
|
124
|
+
*/
|
|
125
|
+
async fetchScript(url) {
|
|
126
|
+
const response = await fetch(url);
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new Error(`Failed to fetch script ${url}: HTTP ${response.status}`);
|
|
129
|
+
}
|
|
130
|
+
return response.text();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Execute an array of scripts in sequence inside the proxy.
|
|
135
|
+
* External scripts (with src) are fetched first.
|
|
136
|
+
*
|
|
137
|
+
* @param {Array<{content?: string, src?: string}>} scripts
|
|
138
|
+
* @param {string} appName
|
|
139
|
+
* @param {Proxy} proxy
|
|
140
|
+
* @param {Object} [options]
|
|
141
|
+
*/
|
|
142
|
+
async executeAll(scripts, appName, proxy, options = {}) {
|
|
143
|
+
for (const script of scripts) {
|
|
144
|
+
let text = script.content;
|
|
145
|
+
|
|
146
|
+
if (!text && script.src) {
|
|
147
|
+
logger.wuDebug(`[ScriptExecutor] Fetching external script: ${script.src}`);
|
|
148
|
+
text = await this.fetchScript(script.src);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (text && text.trim()) {
|
|
152
|
+
this.execute(text, appName, proxy, {
|
|
153
|
+
...options,
|
|
154
|
+
sourceUrl: script.src || options.sourceUrl || ''
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
logger.wuDebug(`[ScriptExecutor] Executed ${scripts.length} scripts for ${appName}`);
|
|
160
|
+
}
|
|
161
|
+
}
|