@adep/vite-plugin 0.1.3 → 0.1.5
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/dist/ide-proxy.d.ts +16 -0
- package/package.json +1 -1
package/dist/ide-proxy.d.ts
CHANGED
|
@@ -30,6 +30,22 @@
|
|
|
30
30
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
31
31
|
/** 浏览器端 fetch 拦截器脚本(IIFE,纯 JS——必须能直接内联进 script 标签,无 TS / ESM)。 */
|
|
32
32
|
export declare const FN_FETCH_INTERCEPTOR_SCRIPT = "(function () {\n if (window.__adepFnProxyInstalled) return;\n window.__adepFnProxyInstalled = true;\n var ORIGINAL_FETCH = window.fetch.bind(window);\n var pending = {};\n var nextId = 1;\n var TIMEOUT_MS = 15000;\n\n window.addEventListener(\"message\", function (event) {\n var data = event.data;\n if (!data || data.__adepFnResponse !== true) return;\n var entry = pending[data.id];\n if (!entry) return;\n delete pending[data.id];\n clearTimeout(entry.timer);\n var headers;\n try { headers = new Headers(data.headers || {}); }\n catch (e) { headers = new Headers({ \"content-type\": \"text/plain\" }); }\n var body = data.body == null ? null : data.body;\n try {\n entry.resolve(new Response(body, { status: data.status || 200, statusText: \"\", headers: headers }));\n } catch (e2) {\n entry.resolve(new Response(String(body), { status: data.status || 200, headers: { \"content-type\": \"text/plain\" } }));\n }\n });\n\n function readBody(input, init) {\n if (typeof Request !== \"undefined\" && input instanceof Request) {\n return input.text().catch(function () { return null; });\n }\n var body = init && init.body !== undefined ? init.body : input;\n if (body == null) return Promise.resolve(null);\n if (typeof body === \"string\") return Promise.resolve(body);\n if (typeof ArrayBuffer !== \"undefined\" && body instanceof ArrayBuffer) {\n return Promise.resolve(new TextDecoder().decode(body));\n }\n if (typeof Blob !== \"undefined\" && body instanceof Blob) return body.text();\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) {\n return Promise.resolve(body.toString());\n }\n try { return Promise.resolve(String(body)); } catch (e) { return Promise.resolve(null); }\n }\n\n function collectHeaders(input, init) {\n var out = {};\n try { input.headers.forEach(function (v, k) { out[k] = v; }); } catch (e) {}\n if (init && init.headers) {\n try { new Headers(init.headers).forEach(function (v, k) { out[k] = v; }); } catch (e2) {}\n }\n return out;\n }\n\n window.fetch = function (input, init) {\n var urlStr;\n var method;\n var headers = {};\n var isRequest = typeof Request !== \"undefined\" && input instanceof Request;\n if (isRequest) {\n urlStr = String(input.url);\n method = (init && init.method) || input.method || \"GET\";\n headers = collectHeaders(input, init);\n } else if (typeof input === \"string\" || (typeof URL !== \"undefined\" && input instanceof URL)) {\n urlStr = String(input);\n method = (init && init.method) || \"GET\";\n try { new Headers(init && init.headers || {}).forEach(function (v, k) { headers[k] = v; }); } catch (e) {}\n } else {\n return ORIGINAL_FETCH(input, init);\n }\n var u;\n try { u = new URL(urlStr, document.baseURI); }\n catch (e0) {\n try { u = new URL(urlStr, window.location.origin); }\n catch (e1) { return ORIGINAL_FETCH(input, init); }\n }\n if (u.pathname.indexOf(\"/api/\") !== 0 && u.pathname !== \"/api\") {\n return ORIGINAL_FETCH(input, init);\n }\n var bridgeWindow = window.parent !== window ? window.parent : window.opener;\n if (!bridgeWindow) return ORIGINAL_FETCH(input, init);\n method = (method || \"GET\").toUpperCase();\n var target = u.pathname + u.search;\n return readBody(input, init).then(function (textBody) {\n return new Promise(function (resolve) {\n var id = nextId++;\n var timer = setTimeout(function () {\n delete pending[id];\n resolve(new Response('{\"error\":{\"code\":\"FN_PROXY_TIMEOUT\",\"message\":\"\\u4e91\\u51fd\\u6570\\u6267\\u884c\\u8d85\\u65f6\"}}', { status: 504, headers: { \"content-type\": \"application/json\" } }));\n }, TIMEOUT_MS);\n pending[id] = { resolve: resolve, timer: timer };\n bridgeWindow.postMessage({ __adepFnRequest: true, id: id, method: method, url: target, headers: headers, body: textBody }, \"*\");\n });\n });\n };\n\n /* \u2014\u2014 blob URL SPA \u8DEF\u7531\u652F\u6301 \u2014\u2014\n blob: \u662F\u4E0D\u53EF\u5206\u5C42 scheme\uFF0Chistory.pushState('/about') \u5185\u90E8\u89E3\u6790\u76F8\u5BF9\u8DEF\u5F84\u4F1A\u629B\n TypeError \u2192 SPA history \u6A21\u5F0F\u8DEF\u7531\u5D29\u6E83\u3002patch pushState/replaceState\uFF0C\u5BF9\u76F8\u5BF9\n \u8DEF\u5F84\u76F4\u63A5\u541E\u6389\uFF08\u4E0D\u5BFC\u822A\u3001\u4E0D\u629B\u9519\uFF09\uFF0C\u8DEF\u7531\u5E93\u5185\u90E8\u72B6\u6001\u81EA\u884C\u66F4\u65B0\uFF1Blocation.pathname\n \u8986\u76D6\u4E3A\u5F53\u524D\u8DEF\u7531\u8DEF\u5F84\uFF0C\u4F9B\u8DEF\u7531\u5E93\u521D\u59CB\u5316\u65F6\u8BFB\u53D6\u3002sessionStorage \u6301\u4E45\u5316\uFF0C\u5237\u65B0\u540E\u6062\u590D\u3002 */\n if (window.location.protocol === \"blob:\") {\n var SPA_KEY = \"__adep_spa_path\";\n var spaPath = \"/\";\n try {\n var _saved = window.sessionStorage.getItem(SPA_KEY);\n if (_saved) spaPath = _saved;\n } catch (e) {}\n try {\n Object.defineProperty(window.location, \"pathname\", {\n get: function () { return spaPath; },\n configurable: true\n });\n } catch (e) {}\n var _origPush = window.history.pushState.bind(window.history);\n var _origReplace = window.history.replaceState.bind(window.history);\n function _isRelative(url) {\n if (!url || typeof url !== \"string\") return false;\n if (url.charAt(0) === \"#\") return false;\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) return false;\n return true;\n }\n function _resolvePath(url) {\n var qi = url.indexOf(\"?\");\n var hi = url.indexOf(\"#\");\n var end = url.length;\n if (qi !== -1) end = qi;\n if (hi !== -1 && hi < end) end = hi;\n var p = url.slice(0, end);\n if (p.charAt(0) !== \"/\") {\n var base = spaPath.slice(0, spaPath.lastIndexOf(\"/\") + 1);\n p = base + p;\n }\n var parts = p.split(\"/\");\n var out = [];\n for (var i = 0; i < parts.length; i++) {\n var seg = parts[i];\n if (seg === \"\" || seg === \".\") continue;\n if (seg === \"..\") { out.pop(); continue; }\n out.push(seg);\n }\n return \"/\" + out.join(\"/\");\n }\n window.history.pushState = function (state, title, url) {\n if (_isRelative(url)) {\n spaPath = _resolvePath(url);\n try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}\n return;\n }\n return _origPush(state, title, url);\n };\n window.history.replaceState = function (state, title, url) {\n if (_isRelative(url)) {\n spaPath = _resolvePath(url);\n try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}\n return;\n }\n return _origReplace(state, title, url);\n };\n }\n})();";
|
|
33
|
+
/**
|
|
34
|
+
* 浏览器端控制台中继脚本(IIFE,纯 JS——必须能直接内联进 script 标签,无 TS / ESM)。
|
|
35
|
+
*
|
|
36
|
+
* **同步纪律**:本字符串与 `packages/web-container/src/console-relay.ts` 的
|
|
37
|
+
* `CONSOLE_RELAY_SCRIPT`(浏览器内置 vite-dev 注入用)**逐字一致**——理由同上面的拦截器:
|
|
38
|
+
* 预览 iframe / 浏览器内 vite-dev 是两个独立加载上下文,不共享 import,只共享文本契约。
|
|
39
|
+
* 机检见 `app/composables/__tests__/preview-inject-scripts.test.ts`(两份副本逐字比对)。
|
|
40
|
+
*
|
|
41
|
+
* 两条注入路径:
|
|
42
|
+
* - Nodebox:`app/composables/ide-nodebox-preview.ts` 把它写进沙箱内的注入插件(transformIndexHtml);
|
|
43
|
+
* - 浏览器内置 dev server:`vite-dev.ts` 在 buildDocument 里内联进产物文档 `<head>` 首位。
|
|
44
|
+
*
|
|
45
|
+
* 信封 `{ source: 'adep-ide-preview', kind: 'console', level, text }` 由 IDE 的
|
|
46
|
+
* `FrontendPreview.onMessage` 消费;`window.parent === window`(直接打开 / 分享链接)不发。
|
|
47
|
+
*/
|
|
48
|
+
export declare const CONSOLE_RELAY_SCRIPT = "(function () {\n if (window.__adepErrorRelayInstalled) return;\n window.__adepErrorRelayInstalled = true;\n var LEVELS = { log: \"log\", info: \"info\", warn: \"warn\", error: \"error\", debug: \"log\" };\n function fmt(value) {\n try {\n if (typeof value === \"string\") return value;\n if (value === undefined) return \"undefined\";\n var seen = [];\n var json = JSON.stringify(value, function (key, val) {\n if (val instanceof Error) return val.stack || (val.name + \": \" + val.message);\n if (typeof val === \"function\") return \"[Function \" + (val.name || \"anonymous\") + \"]\";\n if (typeof val === \"bigint\") return String(val) + \"n\";\n if (val && typeof val === \"object\") {\n if (seen.indexOf(val) !== -1) return \"[Circular]\";\n seen.push(val);\n }\n return val;\n });\n return json === undefined ? String(value) : json;\n } catch {\n return String(value);\n }\n }\n function send(level, args) {\n try {\n if (window.parent === window) return;\n var text = Array.prototype.map.call(args, fmt).join(\" \");\n window.parent.postMessage({ source: \"adep-ide-preview\", kind: \"console\", level: level, text: text }, \"*\");\n } catch {\n }\n }\n Object.keys(LEVELS).forEach(function (name) {\n var native = console[name];\n console[name] = function () {\n send(LEVELS[name], arguments);\n native.apply(console, arguments);\n };\n });\n window.addEventListener('error', function (event) {\n var text = event.message || \"Script error\";\n if (event.filename) {\n text += \" (\" + event.filename + \":\" + event.lineno + \":\" + event.colno + \")\";\n }\n send(\"error\", [text]);\n });\n window.addEventListener('unhandledrejection', function (event) {\n var reason = event.reason;\n var text = reason && reason.stack ? String(reason.stack) : \"Unhandled rejection: \" + fmt(reason);\n send(\"error\", [text]);\n });\n})();\n";
|
|
33
49
|
/**
|
|
34
50
|
* 构造中间件:serve `/@adep/fn-proxy.js`(返回上面的拦截器脚本)。
|
|
35
51
|
* vite dev / preview server 均挂;路径未命中则 next() 放行。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adep/vite-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "云函数 Vite 插件(IDE-030,自 CLI-014 @adep/cli/vite 抽出):vite dev 进程内启动本地 adep dev server 并代理 /{prefix}/* 到云函数;同时 serve /@adep/fn-proxy.js(Web IDE 预览 fetch 拦截器)。本地运行时与配置加载经 createDevServer / loadConfig 注入端口接入,供 CLI / Web IDE / 非 CLI 用户独立使用。",
|