@uni_toolkit/uniapp-miniprogram-devtool 0.1.1-alpha.1778855349600
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/LICENSE +21 -0
- package/README.md +176 -0
- package/bin/umpd.js +16 -0
- package/dist/automator-inspector.cjs +172 -0
- package/dist/automator-inspector.cjs.map +1 -0
- package/dist/automator-inspector.d.cts +35 -0
- package/dist/chunk-CKQMccvm.cjs +28 -0
- package/dist/cli.cjs +33 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +5 -0
- package/dist/core.cjs +593 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +71 -0
- package/dist/html-report.cjs +75 -0
- package/dist/html-report.cjs.map +1 -0
- package/dist/html-report.d.cts +7 -0
- package/dist/one-click.cjs +223 -0
- package/dist/one-click.cjs.map +1 -0
- package/dist/one-click.d.cts +5 -0
- package/dist/runtime-snippet.cjs +116 -0
- package/dist/runtime-snippet.cjs.map +1 -0
- package/dist/runtime-snippet.d.cts +7 -0
- package/dist/web-panel.cjs +882 -0
- package/dist/web-panel.cjs.map +1 -0
- package/dist/web-panel.d.cts +50 -0
- package/package.json +60 -0
package/dist/core.d.cts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
type Confidence = 'high' | 'medium' | 'low' | 'generated';
|
|
3
|
+
interface SourceMapInfo {
|
|
4
|
+
path: string;
|
|
5
|
+
sources: string[];
|
|
6
|
+
sourcesContent: string[];
|
|
7
|
+
names: string[];
|
|
8
|
+
}
|
|
9
|
+
interface WxmlUsage {
|
|
10
|
+
index: number;
|
|
11
|
+
snippet: string;
|
|
12
|
+
}
|
|
13
|
+
interface TemplateAttribute {
|
|
14
|
+
name: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
interface TemplateNode {
|
|
18
|
+
id: string;
|
|
19
|
+
tag: string;
|
|
20
|
+
kind: 'element' | 'component' | 'text';
|
|
21
|
+
snippet: string;
|
|
22
|
+
keyRefs: string[];
|
|
23
|
+
attrs: TemplateAttribute[];
|
|
24
|
+
text: string | null;
|
|
25
|
+
children: TemplateNode[];
|
|
26
|
+
}
|
|
27
|
+
interface KeyMapItem {
|
|
28
|
+
key: string;
|
|
29
|
+
sourceName: string | null;
|
|
30
|
+
generatedName: string | null;
|
|
31
|
+
kind: string;
|
|
32
|
+
confidence: Confidence;
|
|
33
|
+
expressionSummary: string;
|
|
34
|
+
expression: string;
|
|
35
|
+
wxmlUsages: WxmlUsage[];
|
|
36
|
+
}
|
|
37
|
+
interface PageAnalysis {
|
|
38
|
+
page: string;
|
|
39
|
+
jsFile: string;
|
|
40
|
+
wxmlFile: string | null;
|
|
41
|
+
sourceMap: SourceMapInfo | null;
|
|
42
|
+
keys: KeyMapItem[];
|
|
43
|
+
templateTree: TemplateNode | null;
|
|
44
|
+
}
|
|
45
|
+
interface ProjectAnalysis {
|
|
46
|
+
tool: 'uniappx-keymap-devtools';
|
|
47
|
+
version: string;
|
|
48
|
+
targetRoot: string;
|
|
49
|
+
generatedAt: string;
|
|
50
|
+
pages: Record<string, PageAnalysis>;
|
|
51
|
+
}
|
|
52
|
+
interface ParsedProperty {
|
|
53
|
+
key: string;
|
|
54
|
+
expression: string;
|
|
55
|
+
}
|
|
56
|
+
interface InferredExpression {
|
|
57
|
+
sourceName: string | null;
|
|
58
|
+
generatedName: string | null;
|
|
59
|
+
kind: string;
|
|
60
|
+
confidence: Confidence;
|
|
61
|
+
expressionSummary: string;
|
|
62
|
+
}
|
|
63
|
+
declare function extractReturnedObject(js: string): string | null;
|
|
64
|
+
declare function splitTopLevelProperties(body: string): string[];
|
|
65
|
+
declare function parseProperty(part: string): ParsedProperty | null;
|
|
66
|
+
declare function inferFromExpression(expression: string, setupBindings: Set<string>): InferredExpression;
|
|
67
|
+
declare function analyzePage(targetRoot: string, jsFile: string): PageAnalysis;
|
|
68
|
+
declare function analyzeProject(targetRoot: string): ProjectAnalysis;
|
|
69
|
+
//#endregion
|
|
70
|
+
export { Confidence, KeyMapItem, PageAnalysis, ProjectAnalysis, SourceMapInfo, TemplateAttribute, TemplateNode, WxmlUsage, analyzePage, analyzeProject, extractReturnedObject, inferFromExpression, parseProperty, splitTopLevelProperties };
|
|
71
|
+
//# sourceMappingURL=core.d.cts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/html-report.ts
|
|
3
|
+
function escapeHtml(value) {
|
|
4
|
+
return String(value == null ? "" : value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5
|
+
}
|
|
6
|
+
function renderHtmlReport(result) {
|
|
7
|
+
const pageCards = Object.values(result.pages).map((page) => {
|
|
8
|
+
const rows = page.keys.map((item) => {
|
|
9
|
+
const source = item.sourceName || item.generatedName || "unknown";
|
|
10
|
+
const usage = item.wxmlUsages.map((u) => `<code>${escapeHtml(u.snippet)}</code>`).join("<br>") || "<span class=\"muted\">not found</span>";
|
|
11
|
+
return `<tr>
|
|
12
|
+
<td><span class="key">${escapeHtml(item.key)}</span></td>
|
|
13
|
+
<td>${escapeHtml(source)}</td>
|
|
14
|
+
<td><span class="pill ${escapeHtml(item.confidence)}">${escapeHtml(item.confidence)}</span></td>
|
|
15
|
+
<td><code>${escapeHtml(item.expressionSummary || item.expression)}</code></td>
|
|
16
|
+
<td>${usage}</td>
|
|
17
|
+
</tr>`;
|
|
18
|
+
}).join("\n");
|
|
19
|
+
const sourcePreview = page.sourceMap?.sourcesContent?.[0] ? `<details><summary>Source preview</summary><pre>${escapeHtml(page.sourceMap.sourcesContent[0])}</pre></details>` : "";
|
|
20
|
+
return `<section class="card">
|
|
21
|
+
<div class="card-title">
|
|
22
|
+
<h2>${escapeHtml(page.page)}</h2>
|
|
23
|
+
<span>${escapeHtml(page.jsFile)}</span>
|
|
24
|
+
</div>
|
|
25
|
+
<table>
|
|
26
|
+
<thead><tr><th>Compiled key</th><th>Readable source</th><th>Confidence</th><th>Compiled expression</th><th>WXML usage</th></tr></thead>
|
|
27
|
+
<tbody>${rows || "<tr><td colspan=\"5\" class=\"muted\">No __returned__ keys found.</td></tr>"}</tbody>
|
|
28
|
+
</table>
|
|
29
|
+
${sourcePreview}
|
|
30
|
+
</section>`;
|
|
31
|
+
}).join("\n");
|
|
32
|
+
return `<!doctype html>
|
|
33
|
+
<html lang="en">
|
|
34
|
+
<head>
|
|
35
|
+
<meta charset="utf-8">
|
|
36
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
37
|
+
<title>uniappx keymap report</title>
|
|
38
|
+
<style>
|
|
39
|
+
:root { --ink:#18231f; --muted:#68736d; --paper:#f7f0df; --card:#fffaf0; --line:#dfd3b9; --green:#1f7a54; --amber:#a66b00; --red:#a43b32; }
|
|
40
|
+
* { box-sizing: border-box; }
|
|
41
|
+
body { margin:0; color:var(--ink); background:radial-gradient(circle at 20% 0%, #d8f0c8 0, transparent 28rem), linear-gradient(135deg, #f7f0df, #efe1c1); font:15px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
42
|
+
header { padding:42px clamp(20px, 5vw, 70px) 24px; }
|
|
43
|
+
h1 { margin:0 0 8px; font:800 clamp(32px, 6vw, 72px)/.95 Georgia, 'Times New Roman', serif; letter-spacing:-.05em; }
|
|
44
|
+
header p { margin:0; color:var(--muted); max-width:900px; }
|
|
45
|
+
main { padding:0 clamp(20px, 5vw, 70px) 60px; display:grid; gap:22px; }
|
|
46
|
+
.card { background:rgba(255,250,240,.92); border:1px solid var(--line); border-radius:24px; box-shadow:0 22px 70px rgba(61,44,15,.12); overflow:hidden; }
|
|
47
|
+
.card-title { display:flex; justify-content:space-between; gap:16px; align-items:flex-end; padding:22px 24px; border-bottom:1px solid var(--line); }
|
|
48
|
+
h2 { margin:0; font:700 26px/1.1 Georgia, 'Times New Roman', serif; }
|
|
49
|
+
.card-title span, .muted { color:var(--muted); }
|
|
50
|
+
table { width:100%; border-collapse:collapse; }
|
|
51
|
+
th, td { text-align:left; vertical-align:top; padding:14px 16px; border-bottom:1px solid #eadfc7; }
|
|
52
|
+
th { font-size:12px; text-transform:uppercase; color:var(--muted); letter-spacing:.08em; }
|
|
53
|
+
code { background:#f0e5cd; border:1px solid #e1d2b6; border-radius:7px; padding:2px 5px; white-space:pre-wrap; word-break:break-word; }
|
|
54
|
+
.key { display:inline-grid; place-items:center; min-width:34px; min-height:34px; border-radius:12px; background:var(--ink); color:var(--paper); font-weight:800; }
|
|
55
|
+
.pill { display:inline-block; border-radius:999px; padding:3px 9px; color:white; font-size:12px; }
|
|
56
|
+
.pill.high { background:var(--green); } .pill.medium { background:var(--amber); } .pill.low { background:var(--red); } .pill.generated { background:#4d665b; }
|
|
57
|
+
details { padding:16px 24px 24px; }
|
|
58
|
+
summary { cursor:pointer; color:var(--green); font-weight:700; }
|
|
59
|
+
pre { overflow:auto; background:#1e2924; color:#f8f0dc; border-radius:16px; padding:18px; }
|
|
60
|
+
@media (max-width: 760px) { .card-title { display:block; } table, thead, tbody, tr, th, td { display:block; } thead { display:none; } td { border-bottom:0; padding:8px 16px; } tr { border-bottom:1px solid var(--line); padding:10px 0; } }
|
|
61
|
+
</style>
|
|
62
|
+
</head>
|
|
63
|
+
<body>
|
|
64
|
+
<header>
|
|
65
|
+
<h1>uniappx keymap</h1>
|
|
66
|
+
<p>Generated at ${escapeHtml(result.generatedAt)} for <code>${escapeHtml(result.targetRoot)}</code>. This report makes compiled mini-program keys like <code>a</code>, <code>b</code>, <code>c</code> readable during development.</p>
|
|
67
|
+
</header>
|
|
68
|
+
<main>${pageCards || "<p>No pages found.</p>"}</main>
|
|
69
|
+
</body>
|
|
70
|
+
</html>`;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
exports.renderHtmlReport = renderHtmlReport;
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=html-report.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-report.cjs","names":[],"sources":["../src/html-report.ts"],"sourcesContent":["import type { ProjectAnalysis } from './core';\n\nfunction escapeHtml(value: unknown): string {\n return String(value == null ? '' : value)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nexport function renderHtmlReport(result: ProjectAnalysis): string {\n const pages = Object.values(result.pages);\n const pageCards = pages\n .map((page) => {\n const rows = page.keys\n .map((item) => {\n const source = item.sourceName || item.generatedName || 'unknown';\n const usage =\n item.wxmlUsages.map((u) => `<code>${escapeHtml(u.snippet)}</code>`).join('<br>') ||\n '<span class=\"muted\">not found</span>';\n return `<tr>\n <td><span class=\"key\">${escapeHtml(item.key)}</span></td>\n <td>${escapeHtml(source)}</td>\n <td><span class=\"pill ${escapeHtml(item.confidence)}\">${escapeHtml(item.confidence)}</span></td>\n <td><code>${escapeHtml(item.expressionSummary || item.expression)}</code></td>\n <td>${usage}</td>\n </tr>`;\n })\n .join('\\n');\n\n const sourcePreview = page.sourceMap?.sourcesContent?.[0]\n ? `<details><summary>Source preview</summary><pre>${escapeHtml(page.sourceMap.sourcesContent[0])}</pre></details>`\n : '';\n\n return `<section class=\"card\">\n <div class=\"card-title\">\n <h2>${escapeHtml(page.page)}</h2>\n <span>${escapeHtml(page.jsFile)}</span>\n </div>\n <table>\n <thead><tr><th>Compiled key</th><th>Readable source</th><th>Confidence</th><th>Compiled expression</th><th>WXML usage</th></tr></thead>\n <tbody>${rows || '<tr><td colspan=\"5\" class=\"muted\">No __returned__ keys found.</td></tr>'}</tbody>\n </table>\n ${sourcePreview}\n </section>`;\n })\n .join('\\n');\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>uniappx keymap report</title>\n<style>\n:root { --ink:#18231f; --muted:#68736d; --paper:#f7f0df; --card:#fffaf0; --line:#dfd3b9; --green:#1f7a54; --amber:#a66b00; --red:#a43b32; }\n* { box-sizing: border-box; }\nbody { margin:0; color:var(--ink); background:radial-gradient(circle at 20% 0%, #d8f0c8 0, transparent 28rem), linear-gradient(135deg, #f7f0df, #efe1c1); font:15px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }\nheader { padding:42px clamp(20px, 5vw, 70px) 24px; }\nh1 { margin:0 0 8px; font:800 clamp(32px, 6vw, 72px)/.95 Georgia, 'Times New Roman', serif; letter-spacing:-.05em; }\nheader p { margin:0; color:var(--muted); max-width:900px; }\nmain { padding:0 clamp(20px, 5vw, 70px) 60px; display:grid; gap:22px; }\n.card { background:rgba(255,250,240,.92); border:1px solid var(--line); border-radius:24px; box-shadow:0 22px 70px rgba(61,44,15,.12); overflow:hidden; }\n.card-title { display:flex; justify-content:space-between; gap:16px; align-items:flex-end; padding:22px 24px; border-bottom:1px solid var(--line); }\nh2 { margin:0; font:700 26px/1.1 Georgia, 'Times New Roman', serif; }\n.card-title span, .muted { color:var(--muted); }\ntable { width:100%; border-collapse:collapse; }\nth, td { text-align:left; vertical-align:top; padding:14px 16px; border-bottom:1px solid #eadfc7; }\nth { font-size:12px; text-transform:uppercase; color:var(--muted); letter-spacing:.08em; }\ncode { background:#f0e5cd; border:1px solid #e1d2b6; border-radius:7px; padding:2px 5px; white-space:pre-wrap; word-break:break-word; }\n.key { display:inline-grid; place-items:center; min-width:34px; min-height:34px; border-radius:12px; background:var(--ink); color:var(--paper); font-weight:800; }\n.pill { display:inline-block; border-radius:999px; padding:3px 9px; color:white; font-size:12px; }\n.pill.high { background:var(--green); } .pill.medium { background:var(--amber); } .pill.low { background:var(--red); } .pill.generated { background:#4d665b; }\ndetails { padding:16px 24px 24px; }\nsummary { cursor:pointer; color:var(--green); font-weight:700; }\npre { overflow:auto; background:#1e2924; color:#f8f0dc; border-radius:16px; padding:18px; }\n@media (max-width: 760px) { .card-title { display:block; } table, thead, tbody, tr, th, td { display:block; } thead { display:none; } td { border-bottom:0; padding:8px 16px; } tr { border-bottom:1px solid var(--line); padding:10px 0; } }\n</style>\n</head>\n<body>\n<header>\n <h1>uniappx keymap</h1>\n <p>Generated at ${escapeHtml(result.generatedAt)} for <code>${escapeHtml(result.targetRoot)}</code>. This report makes compiled mini-program keys like <code>a</code>, <code>b</code>, <code>c</code> readable during development.</p>\n</header>\n<main>${pageCards || '<p>No pages found.</p>'}</main>\n</body>\n</html>`;\n}\n"],"mappings":";;AAEA,SAAS,WAAW,OAAwB;AAC1C,QAAO,OAAO,SAAS,OAAO,KAAK,MAAM,CACtC,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,SAAS;;AAG5B,SAAgB,iBAAiB,QAAiC;CAEhE,MAAM,YADQ,OAAO,OAAO,OAAO,MAAM,CAEtC,KAAK,SAAS;EACb,MAAM,OAAO,KAAK,KACf,KAAK,SAAS;GACb,MAAM,SAAS,KAAK,cAAc,KAAK,iBAAiB;GACxD,MAAM,QACJ,KAAK,WAAW,KAAK,MAAM,SAAS,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,OAAO,IAChF;AACF,UAAO;gCACe,WAAW,KAAK,IAAI,CAAC;cACvC,WAAW,OAAO,CAAC;gCACD,WAAW,KAAK,WAAW,CAAC,IAAI,WAAW,KAAK,WAAW,CAAC;oBACxE,WAAW,KAAK,qBAAqB,KAAK,WAAW,CAAC;cAC5D,MAAM;;IAEV,CACD,KAAK,KAAK;EAEb,MAAM,gBAAgB,KAAK,WAAW,iBAAiB,KACnD,kDAAkD,WAAW,KAAK,UAAU,eAAe,GAAG,CAAC,oBAC/F;AAEJ,SAAO;;cAEC,WAAW,KAAK,KAAK,CAAC;gBACpB,WAAW,KAAK,OAAO,CAAC;;;;iBAIvB,QAAQ,8EAA0E;;QAE3F,cAAc;;GAEhB,CACD,KAAK,KAAK;AAEb,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAkCW,WAAW,OAAO,YAAY,CAAC,aAAa,WAAW,OAAO,WAAW,CAAC;;QAEtF,aAAa,yBAAyB"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_chunk = require("./chunk-CKQMccvm.cjs");
|
|
3
|
+
const require_automator_inspector = require("./automator-inspector.cjs");
|
|
4
|
+
const require_core = require("./core.cjs");
|
|
5
|
+
const require_html_report = require("./html-report.cjs");
|
|
6
|
+
const require_web_panel = require("./web-panel.cjs");
|
|
7
|
+
let node_fs = require("node:fs");
|
|
8
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
9
|
+
let node_os = require("node:os");
|
|
10
|
+
node_os = require_chunk.__toESM(node_os);
|
|
11
|
+
let node_path = require("node:path");
|
|
12
|
+
node_path = require_chunk.__toESM(node_path);
|
|
13
|
+
//#region src/one-click.ts
|
|
14
|
+
const OUTPUT_DIR = node_path.default.join(node_os.default.tmpdir(), "uniapp-miniprogram-devtool");
|
|
15
|
+
const PROJECT_OPTIONS = [
|
|
16
|
+
"--project",
|
|
17
|
+
"--proj",
|
|
18
|
+
"-p"
|
|
19
|
+
];
|
|
20
|
+
const WECHAT_DEVTOOLS_OPTIONS = [
|
|
21
|
+
"--wechat-devtools",
|
|
22
|
+
"--wd",
|
|
23
|
+
"-w"
|
|
24
|
+
];
|
|
25
|
+
const CLI_PATH_OPTIONS = ["--cli-path"];
|
|
26
|
+
const PORT_OPTIONS = ["--port"];
|
|
27
|
+
const VALUE_OPTIONS = new Set([
|
|
28
|
+
...PROJECT_OPTIONS,
|
|
29
|
+
...WECHAT_DEVTOOLS_OPTIONS,
|
|
30
|
+
...CLI_PATH_OPTIONS,
|
|
31
|
+
...PORT_OPTIONS
|
|
32
|
+
]);
|
|
33
|
+
function isMpWeixinRoot(dir) {
|
|
34
|
+
return node_fs.default.existsSync(node_path.default.join(dir, "app.json")) && node_fs.default.existsSync(node_path.default.join(dir, "app.js"));
|
|
35
|
+
}
|
|
36
|
+
function safeStat(file) {
|
|
37
|
+
try {
|
|
38
|
+
return node_fs.default.statSync(file);
|
|
39
|
+
} catch (_error) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function normalizeCliPath(value) {
|
|
44
|
+
const resolved = node_path.default.resolve(value);
|
|
45
|
+
if (resolved.endsWith(".app")) return node_path.default.join(resolved, "Contents", "MacOS", "cli");
|
|
46
|
+
return resolved;
|
|
47
|
+
}
|
|
48
|
+
function getOptionValue(argv, name) {
|
|
49
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
50
|
+
const arg = argv[index];
|
|
51
|
+
if (arg === name) return argv[index + 1];
|
|
52
|
+
if (arg.startsWith(`${name}=`)) return arg.slice(name.length + 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function getAnyOptionValue(argv, names) {
|
|
56
|
+
for (const name of names) {
|
|
57
|
+
const value = getOptionValue(argv, name);
|
|
58
|
+
if (value) return value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function firstPositionalArg(argv) {
|
|
62
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
63
|
+
const arg = argv[index];
|
|
64
|
+
const optionName = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
|
|
65
|
+
if (VALUE_OPTIONS.has(optionName)) {
|
|
66
|
+
if (!arg.includes("=")) index += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (!arg.startsWith("-")) return arg;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function getRequiredTarget(argv) {
|
|
73
|
+
const explicitTarget = getAnyOptionValue(argv, PROJECT_OPTIONS) || firstPositionalArg(argv);
|
|
74
|
+
if (!explicitTarget) throw new Error("请显式传入 uni-app / uni-app x 微信小程序编译产物目录,例如:umpd -p ./unpackage/dist/dev/mp-weixin");
|
|
75
|
+
const resolved = node_path.default.resolve(explicitTarget);
|
|
76
|
+
if (!isMpWeixinRoot(resolved)) throw new Error(`不是有效的 mp-weixin 产物目录:${resolved}。请确认该目录包含 app.json 和 app.js。`);
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
function getRequiredCliPath(argv) {
|
|
80
|
+
const rawCliPath = getAnyOptionValue(argv, CLI_PATH_OPTIONS) || getAnyOptionValue(argv, WECHAT_DEVTOOLS_OPTIONS);
|
|
81
|
+
if (!rawCliPath) throw new Error("请显式传入微信开发者工具路径,例如:umpd -w /Volumes/Elements/Applications/wechatwebdevtools.app");
|
|
82
|
+
const cliPath = normalizeCliPath(rawCliPath);
|
|
83
|
+
if (!node_fs.default.existsSync(cliPath)) throw new Error(`不是有效的微信开发者工具路径:${rawCliPath}。可以通过 -w 直接传 .app 路径。`);
|
|
84
|
+
return cliPath;
|
|
85
|
+
}
|
|
86
|
+
function writeText(file, content) {
|
|
87
|
+
node_fs.default.mkdirSync(node_path.default.dirname(file), { recursive: true });
|
|
88
|
+
node_fs.default.writeFileSync(file, content);
|
|
89
|
+
}
|
|
90
|
+
function latestTreeMtime(root) {
|
|
91
|
+
let latest = 0;
|
|
92
|
+
function walk(dir) {
|
|
93
|
+
let entries;
|
|
94
|
+
try {
|
|
95
|
+
entries = node_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
96
|
+
} catch (_error) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
const full = node_path.default.join(dir, entry.name);
|
|
101
|
+
if (entry.isDirectory()) {
|
|
102
|
+
if (entry.name === "common") continue;
|
|
103
|
+
walk(full);
|
|
104
|
+
} else if (/\.(js|wxml|map)$/.test(entry.name)) latest = Math.max(latest, safeStat(full)?.mtimeMs || 0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
walk(root);
|
|
108
|
+
return latest;
|
|
109
|
+
}
|
|
110
|
+
function generate(targetRoot) {
|
|
111
|
+
const result = require_core.analyzeProject(targetRoot);
|
|
112
|
+
const keymapPath = node_path.default.join(OUTPUT_DIR, "uniapp-miniprogram-devtool.json");
|
|
113
|
+
const htmlPath = node_path.default.join(OUTPUT_DIR, "uniapp-miniprogram-devtool.html");
|
|
114
|
+
writeText(keymapPath, JSON.stringify(result, null, 2));
|
|
115
|
+
writeText(htmlPath, require_html_report.renderHtmlReport(result));
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function printStartup(targetRoot, result) {
|
|
119
|
+
const htmlPath = node_path.default.join(OUTPUT_DIR, "uniapp-miniprogram-devtool.html");
|
|
120
|
+
const pageCount = Object.keys(result.pages).length;
|
|
121
|
+
const keyCount = Object.values(result.pages).reduce((sum, page) => sum + page.keys.length, 0);
|
|
122
|
+
console.clear();
|
|
123
|
+
console.log("uniapp-miniprogram-devtool");
|
|
124
|
+
console.log("目标目录:", targetRoot);
|
|
125
|
+
console.log("页面数:", pageCount, "键数量:", keyCount);
|
|
126
|
+
console.log("报告文件:", htmlPath);
|
|
127
|
+
console.log("");
|
|
128
|
+
console.log("正在启动并连接微信开发者工具自动化...");
|
|
129
|
+
}
|
|
130
|
+
async function main(argv) {
|
|
131
|
+
const cliPath = getRequiredCliPath(argv);
|
|
132
|
+
const panelPort = Number(getOptionValue(argv, "--port") || process.env.UNIAPP_MINIPROGRAM_DEVTOOL_PORT || process.env.UNIAPPX_KEYMAP_PORT || 17890);
|
|
133
|
+
const targetRoot = getRequiredTarget(argv);
|
|
134
|
+
let lastMtime = 0;
|
|
135
|
+
let currentAnalysis = generate(targetRoot);
|
|
136
|
+
printStartup(targetRoot, currentAnalysis);
|
|
137
|
+
let pollTimer;
|
|
138
|
+
let stopInspector;
|
|
139
|
+
let reconnectPromise = null;
|
|
140
|
+
let shuttingDown = false;
|
|
141
|
+
function updatePanelStatus(status) {
|
|
142
|
+
webPanel.update({
|
|
143
|
+
connected: false,
|
|
144
|
+
status,
|
|
145
|
+
route: "",
|
|
146
|
+
rows: [],
|
|
147
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function disposeInspector() {
|
|
151
|
+
stopInspector?.();
|
|
152
|
+
stopInspector = void 0;
|
|
153
|
+
}
|
|
154
|
+
async function reconnectInspector(status = "正在启动微信开发者工具自动化...") {
|
|
155
|
+
if (shuttingDown) return;
|
|
156
|
+
if (reconnectPromise) return reconnectPromise;
|
|
157
|
+
updatePanelStatus(status);
|
|
158
|
+
reconnectPromise = (async () => {
|
|
159
|
+
disposeInspector();
|
|
160
|
+
regenerateIfNeeded(true);
|
|
161
|
+
try {
|
|
162
|
+
stopInspector = await require_automator_inspector.startAutomatorInspector({
|
|
163
|
+
projectPath: targetRoot,
|
|
164
|
+
getAnalysis: () => currentAnalysis,
|
|
165
|
+
intervalMs: 500,
|
|
166
|
+
cliPath,
|
|
167
|
+
suppressTerminal: true,
|
|
168
|
+
onSnapshot: (snapshot) => webPanel.update(snapshot)
|
|
169
|
+
});
|
|
170
|
+
process.exitCode = 0;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
const message = require_automator_inspector.explainAutomatorFailure(error);
|
|
173
|
+
webPanel.update({
|
|
174
|
+
connected: false,
|
|
175
|
+
status: message,
|
|
176
|
+
route: "",
|
|
177
|
+
rows: [],
|
|
178
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
179
|
+
});
|
|
180
|
+
console.error(message);
|
|
181
|
+
process.exitCode = 1;
|
|
182
|
+
} finally {
|
|
183
|
+
reconnectPromise = null;
|
|
184
|
+
}
|
|
185
|
+
})();
|
|
186
|
+
return reconnectPromise;
|
|
187
|
+
}
|
|
188
|
+
async function shutdown(exitCode) {
|
|
189
|
+
if (shuttingDown) return;
|
|
190
|
+
shuttingDown = true;
|
|
191
|
+
pollTimer && clearInterval(pollTimer);
|
|
192
|
+
disposeInspector();
|
|
193
|
+
webPanel.close();
|
|
194
|
+
if (typeof exitCode === "number") process.exit(exitCode);
|
|
195
|
+
}
|
|
196
|
+
const webPanel = await require_web_panel.startWebPanel({
|
|
197
|
+
port: panelPort,
|
|
198
|
+
onReconnect: () => reconnectInspector("正在重新连接微信开发者工具自动化...")
|
|
199
|
+
});
|
|
200
|
+
console.log("Web 面板:", webPanel.url);
|
|
201
|
+
console.log("运行时变量值会显示在 Web 面板中,按 Ctrl+C 停止。");
|
|
202
|
+
updatePanelStatus("正在启动微信开发者工具自动化...");
|
|
203
|
+
function regenerateIfNeeded(force = false) {
|
|
204
|
+
const mtime = latestTreeMtime(targetRoot);
|
|
205
|
+
if (force || mtime !== lastMtime) {
|
|
206
|
+
lastMtime = mtime;
|
|
207
|
+
currentAnalysis = generate(targetRoot);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
regenerateIfNeeded(true);
|
|
211
|
+
pollTimer = setInterval(() => regenerateIfNeeded(), 1200);
|
|
212
|
+
process.once("SIGINT", () => void shutdown(130));
|
|
213
|
+
process.once("SIGTERM", () => void shutdown(143));
|
|
214
|
+
await reconnectInspector();
|
|
215
|
+
}
|
|
216
|
+
if (require.main === module) main(process.argv.slice(2)).catch((error) => {
|
|
217
|
+
console.error(error?.stack ? error.stack : String(error));
|
|
218
|
+
process.exitCode = 1;
|
|
219
|
+
});
|
|
220
|
+
//#endregion
|
|
221
|
+
exports.main = main;
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=one-click.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-click.cjs","names":["path","os","fs","analyzeProject","renderHtmlReport","startAutomatorInspector","explainAutomatorFailure","startWebPanel"],"sources":["../src/one-click.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { explainAutomatorFailure, startAutomatorInspector } from './automator-inspector';\nimport { analyzeProject, type ProjectAnalysis } from './core';\nimport { renderHtmlReport } from './html-report';\nimport { startWebPanel } from './web-panel';\n\nconst OUTPUT_DIR = path.join(os.tmpdir(), 'uniapp-miniprogram-devtool');\nconst PROJECT_OPTIONS = ['--project', '--proj', '-p'];\nconst WECHAT_DEVTOOLS_OPTIONS = ['--wechat-devtools', '--wd', '-w'];\nconst CLI_PATH_OPTIONS = ['--cli-path'];\nconst PORT_OPTIONS = ['--port'];\nconst VALUE_OPTIONS = new Set([...PROJECT_OPTIONS, ...WECHAT_DEVTOOLS_OPTIONS, ...CLI_PATH_OPTIONS, ...PORT_OPTIONS]);\n\nfunction isMpWeixinRoot(dir: string): boolean {\n return fs.existsSync(path.join(dir, 'app.json')) && fs.existsSync(path.join(dir, 'app.js'));\n}\n\nfunction safeStat(file: string): fs.Stats | null {\n try {\n return fs.statSync(file);\n } catch (_error) {\n return null;\n }\n}\n\nfunction normalizeCliPath(value: string): string {\n const resolved = path.resolve(value);\n if (resolved.endsWith('.app')) return path.join(resolved, 'Contents', 'MacOS', 'cli');\n return resolved;\n}\n\nfunction getOptionValue(argv: string[], name: string): string | undefined {\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === name) return argv[index + 1];\n if (arg.startsWith(`${name}=`)) return arg.slice(name.length + 1);\n }\n return undefined;\n}\n\nfunction getAnyOptionValue(argv: string[], names: string[]): string | undefined {\n for (const name of names) {\n const value = getOptionValue(argv, name);\n if (value) return value;\n }\n return undefined;\n}\n\nfunction firstPositionalArg(argv: string[]): string | undefined {\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n const optionName = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;\n if (VALUE_OPTIONS.has(optionName)) {\n if (!arg.includes('=')) index += 1;\n continue;\n }\n if (!arg.startsWith('-')) return arg;\n }\n return undefined;\n}\n\nfunction getRequiredTarget(argv: string[]): string {\n const explicitTarget = getAnyOptionValue(argv, PROJECT_OPTIONS) || firstPositionalArg(argv);\n if (!explicitTarget) {\n throw new Error(\n '请显式传入 uni-app / uni-app x 微信小程序编译产物目录,例如:umpd -p ./unpackage/dist/dev/mp-weixin',\n );\n }\n\n const resolved = path.resolve(explicitTarget);\n if (!isMpWeixinRoot(resolved)) {\n throw new Error(`不是有效的 mp-weixin 产物目录:${resolved}。请确认该目录包含 app.json 和 app.js。`);\n }\n return resolved;\n}\n\nfunction getRequiredCliPath(argv: string[]): string {\n const rawCliPath = getAnyOptionValue(argv, CLI_PATH_OPTIONS) || getAnyOptionValue(argv, WECHAT_DEVTOOLS_OPTIONS);\n if (!rawCliPath) {\n throw new Error('请显式传入微信开发者工具路径,例如:umpd -w /Volumes/Elements/Applications/wechatwebdevtools.app');\n }\n\n const cliPath = normalizeCliPath(rawCliPath);\n if (!fs.existsSync(cliPath)) {\n throw new Error(`不是有效的微信开发者工具路径:${rawCliPath}。可以通过 -w 直接传 .app 路径。`);\n }\n\n return cliPath;\n}\n\nfunction writeText(file: string, content: string): void {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, content);\n}\n\nfunction latestTreeMtime(root: string): number {\n let latest = 0;\n function walk(dir: string): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch (_error) {\n return;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === 'common') continue;\n walk(full);\n } else if (/\\.(js|wxml|map)$/.test(entry.name)) {\n latest = Math.max(latest, safeStat(full)?.mtimeMs || 0);\n }\n }\n }\n walk(root);\n return latest;\n}\n\nfunction generate(targetRoot: string): ProjectAnalysis {\n const result = analyzeProject(targetRoot);\n const keymapPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.json');\n const htmlPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.html');\n\n writeText(keymapPath, JSON.stringify(result, null, 2));\n writeText(htmlPath, renderHtmlReport(result));\n\n return result;\n}\n\nfunction printStartup(targetRoot: string, result: ProjectAnalysis): void {\n const htmlPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.html');\n const pageCount = Object.keys(result.pages).length;\n const keyCount = Object.values(result.pages).reduce((sum, page) => sum + page.keys.length, 0);\n\n console.clear();\n console.log('uniapp-miniprogram-devtool');\n console.log('目标目录:', targetRoot);\n console.log('页面数:', pageCount, '键数量:', keyCount);\n console.log('报告文件:', htmlPath);\n console.log('');\n console.log('正在启动并连接微信开发者工具自动化...');\n}\n\nexport async function main(argv: string[]): Promise<void> {\n const cliPath = getRequiredCliPath(argv);\n const panelPort = Number(\n getOptionValue(argv, '--port') ||\n process.env.UNIAPP_MINIPROGRAM_DEVTOOL_PORT ||\n process.env.UNIAPPX_KEYMAP_PORT ||\n 17890,\n );\n const targetRoot = getRequiredTarget(argv);\n let lastMtime = 0;\n let currentAnalysis = generate(targetRoot);\n printStartup(targetRoot, currentAnalysis);\n\n let pollTimer: NodeJS.Timeout | undefined;\n let stopInspector: (() => void) | undefined;\n let reconnectPromise: Promise<void> | null = null;\n let shuttingDown = false;\n\n function updatePanelStatus(status: string): void {\n webPanel.update({ connected: false, status, route: '', rows: [], updatedAt: new Date().toISOString() });\n }\n\n function disposeInspector(): void {\n stopInspector?.();\n stopInspector = undefined;\n }\n\n async function reconnectInspector(status = '正在启动微信开发者工具自动化...'): Promise<void> {\n if (shuttingDown) return;\n if (reconnectPromise) return reconnectPromise;\n\n updatePanelStatus(status);\n reconnectPromise = (async () => {\n disposeInspector();\n regenerateIfNeeded(true);\n try {\n stopInspector = await startAutomatorInspector({\n projectPath: targetRoot,\n getAnalysis: () => currentAnalysis,\n intervalMs: 500,\n cliPath,\n suppressTerminal: true,\n onSnapshot: (snapshot) => webPanel.update(snapshot),\n });\n process.exitCode = 0;\n } catch (error) {\n const message = explainAutomatorFailure(error);\n webPanel.update({\n connected: false,\n status: message,\n route: '',\n rows: [],\n updatedAt: new Date().toISOString(),\n });\n console.error(message);\n process.exitCode = 1;\n } finally {\n reconnectPromise = null;\n }\n })();\n\n return reconnectPromise;\n }\n\n async function shutdown(exitCode?: number): Promise<void> {\n if (shuttingDown) return;\n shuttingDown = true;\n pollTimer && clearInterval(pollTimer);\n disposeInspector();\n webPanel.close();\n if (typeof exitCode === 'number') process.exit(exitCode);\n }\n\n const webPanel = await startWebPanel({\n port: panelPort,\n onReconnect: () => reconnectInspector('正在重新连接微信开发者工具自动化...'),\n });\n console.log('Web 面板:', webPanel.url);\n console.log('运行时变量值会显示在 Web 面板中,按 Ctrl+C 停止。');\n updatePanelStatus('正在启动微信开发者工具自动化...');\n\n function regenerateIfNeeded(force = false): void {\n const mtime = latestTreeMtime(targetRoot);\n if (force || mtime !== lastMtime) {\n lastMtime = mtime;\n currentAnalysis = generate(targetRoot);\n }\n }\n\n regenerateIfNeeded(true);\n\n pollTimer = setInterval(() => regenerateIfNeeded(), 1200);\n\n process.once('SIGINT', () => void shutdown(130));\n process.once('SIGTERM', () => void shutdown(143));\n\n await reconnectInspector();\n}\n\nif (require.main === module) {\n main(process.argv.slice(2)).catch((error) => {\n console.error(error?.stack ? error.stack : String(error));\n process.exitCode = 1;\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/runtime-snippet.ts
|
|
3
|
+
function toRuntimeMap(result) {
|
|
4
|
+
const runtimeMap = {};
|
|
5
|
+
for (const page of Object.values(result.pages)) runtimeMap[page.page] = page.keys.map((item) => ({
|
|
6
|
+
key: item.key,
|
|
7
|
+
label: item.sourceName || item.generatedName || item.expressionSummary || "unknown",
|
|
8
|
+
kind: item.kind,
|
|
9
|
+
confidence: item.confidence
|
|
10
|
+
}));
|
|
11
|
+
return runtimeMap;
|
|
12
|
+
}
|
|
13
|
+
function renderRuntimeSnippet(result) {
|
|
14
|
+
return `(function () {
|
|
15
|
+
var KEYMAP = ${JSON.stringify(toRuntimeMap(result), null, 2)};
|
|
16
|
+
var globalObject = typeof globalThis !== "undefined" ? globalThis : typeof wx !== "undefined" ? wx : this;
|
|
17
|
+
var watchTimer = null;
|
|
18
|
+
var lastSnapshotText = "";
|
|
19
|
+
|
|
20
|
+
function getPagesSafe() {
|
|
21
|
+
try {
|
|
22
|
+
return typeof getCurrentPages === "function" ? getCurrentPages() : [];
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function normalizeRoute(route) {
|
|
29
|
+
return route && route.charAt(0) === "/" ? route.slice(1) : route;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function findPage(route) {
|
|
33
|
+
var pages = getPagesSafe();
|
|
34
|
+
if (!route) return pages[pages.length - 1] || null;
|
|
35
|
+
var normalized = normalizeRoute(route);
|
|
36
|
+
for (var index = pages.length - 1; index >= 0; index -= 1) {
|
|
37
|
+
var page = pages[index];
|
|
38
|
+
if (normalizeRoute(page.route || page.__route__) === normalized) return page;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function routeOf(page) {
|
|
44
|
+
return normalizeRoute(page && (page.route || page.__route__)) || "";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function snapshot(route) {
|
|
48
|
+
var page = findPage(route);
|
|
49
|
+
if (!page) return { route: route || "current", error: "No active page found." };
|
|
50
|
+
|
|
51
|
+
var routeName = routeOf(page);
|
|
52
|
+
var entries = KEYMAP[routeName] || [];
|
|
53
|
+
var data = page.data || {};
|
|
54
|
+
return {
|
|
55
|
+
route: routeName,
|
|
56
|
+
values: entries.map(function (item) {
|
|
57
|
+
return {
|
|
58
|
+
key: item.key,
|
|
59
|
+
label: item.label,
|
|
60
|
+
value: data[item.key],
|
|
61
|
+
kind: item.kind,
|
|
62
|
+
confidence: item.confidence
|
|
63
|
+
};
|
|
64
|
+
})
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function table(route) {
|
|
69
|
+
var snap = snapshot(route);
|
|
70
|
+
if (snap.error) {
|
|
71
|
+
console.warn("[uniappx-keymap] " + snap.error);
|
|
72
|
+
return snap;
|
|
73
|
+
}
|
|
74
|
+
if (typeof console.table === "function") console.table(snap.values);
|
|
75
|
+
else console.log("[uniappx-keymap]", snap.values);
|
|
76
|
+
return snap;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function watch(route, interval) {
|
|
80
|
+
unwatch();
|
|
81
|
+
var delay = typeof interval === "number" && interval > 0 ? interval : 500;
|
|
82
|
+
lastSnapshotText = "";
|
|
83
|
+
watchTimer = setInterval(function () {
|
|
84
|
+
var snap = snapshot(route);
|
|
85
|
+
var text = JSON.stringify(snap);
|
|
86
|
+
if (text !== lastSnapshotText) {
|
|
87
|
+
lastSnapshotText = text;
|
|
88
|
+
console.log("[uniappx-keymap] runtime values changed:", snap.route);
|
|
89
|
+
if (!snap.error) table(route);
|
|
90
|
+
else console.warn("[uniappx-keymap] " + snap.error);
|
|
91
|
+
}
|
|
92
|
+
}, delay);
|
|
93
|
+
console.log("[uniappx-keymap] watching runtime values every " + delay + "ms. Call __UNIAPPX_KEYMAP__.unwatch() to stop.");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function unwatch() {
|
|
97
|
+
if (watchTimer) clearInterval(watchTimer);
|
|
98
|
+
watchTimer = null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
globalObject.__UNIAPPX_KEYMAP__ = {
|
|
102
|
+
keymap: KEYMAP,
|
|
103
|
+
snapshot: snapshot,
|
|
104
|
+
table: table,
|
|
105
|
+
watch: watch,
|
|
106
|
+
unwatch: unwatch
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
console.log("[uniappx-keymap] console snippet ready. Try __UNIAPPX_KEYMAP__.table() or __UNIAPPX_KEYMAP__.watch().");
|
|
110
|
+
})();
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
exports.renderRuntimeSnippet = renderRuntimeSnippet;
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=runtime-snippet.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-snippet.cjs","names":[],"sources":["../src/runtime-snippet.ts"],"sourcesContent":["import type { ProjectAnalysis } from './core';\n\ninterface RuntimeKeyInfo {\n key: string;\n label: string;\n kind: string;\n confidence: string;\n}\n\ntype RuntimeMap = Record<string, RuntimeKeyInfo[]>;\n\nfunction toRuntimeMap(result: ProjectAnalysis): RuntimeMap {\n const runtimeMap: RuntimeMap = {};\n for (const page of Object.values(result.pages)) {\n runtimeMap[page.page] = page.keys.map((item) => ({\n key: item.key,\n label: item.sourceName || item.generatedName || item.expressionSummary || 'unknown',\n kind: item.kind,\n confidence: item.confidence,\n }));\n }\n return runtimeMap;\n}\n\nexport function renderRuntimeSnippet(result: ProjectAnalysis): string {\n const json = JSON.stringify(toRuntimeMap(result), null, 2);\n return `(function () {\n var KEYMAP = ${json};\n var globalObject = typeof globalThis !== \"undefined\" ? globalThis : typeof wx !== \"undefined\" ? wx : this;\n var watchTimer = null;\n var lastSnapshotText = \"\";\n\n function getPagesSafe() {\n try {\n return typeof getCurrentPages === \"function\" ? getCurrentPages() : [];\n } catch (error) {\n return [];\n }\n }\n\n function normalizeRoute(route) {\n return route && route.charAt(0) === \"/\" ? route.slice(1) : route;\n }\n\n function findPage(route) {\n var pages = getPagesSafe();\n if (!route) return pages[pages.length - 1] || null;\n var normalized = normalizeRoute(route);\n for (var index = pages.length - 1; index >= 0; index -= 1) {\n var page = pages[index];\n if (normalizeRoute(page.route || page.__route__) === normalized) return page;\n }\n return null;\n }\n\n function routeOf(page) {\n return normalizeRoute(page && (page.route || page.__route__)) || \"\";\n }\n\n function snapshot(route) {\n var page = findPage(route);\n if (!page) return { route: route || \"current\", error: \"No active page found.\" };\n\n var routeName = routeOf(page);\n var entries = KEYMAP[routeName] || [];\n var data = page.data || {};\n return {\n route: routeName,\n values: entries.map(function (item) {\n return {\n key: item.key,\n label: item.label,\n value: data[item.key],\n kind: item.kind,\n confidence: item.confidence\n };\n })\n };\n }\n\n function table(route) {\n var snap = snapshot(route);\n if (snap.error) {\n console.warn(\"[uniappx-keymap] \" + snap.error);\n return snap;\n }\n if (typeof console.table === \"function\") console.table(snap.values);\n else console.log(\"[uniappx-keymap]\", snap.values);\n return snap;\n }\n\n function watch(route, interval) {\n unwatch();\n var delay = typeof interval === \"number\" && interval > 0 ? interval : 500;\n lastSnapshotText = \"\";\n watchTimer = setInterval(function () {\n var snap = snapshot(route);\n var text = JSON.stringify(snap);\n if (text !== lastSnapshotText) {\n lastSnapshotText = text;\n console.log(\"[uniappx-keymap] runtime values changed:\", snap.route);\n if (!snap.error) table(route);\n else console.warn(\"[uniappx-keymap] \" + snap.error);\n }\n }, delay);\n console.log(\"[uniappx-keymap] watching runtime values every \" + delay + \"ms. Call __UNIAPPX_KEYMAP__.unwatch() to stop.\");\n }\n\n function unwatch() {\n if (watchTimer) clearInterval(watchTimer);\n watchTimer = null;\n }\n\n globalObject.__UNIAPPX_KEYMAP__ = {\n keymap: KEYMAP,\n snapshot: snapshot,\n table: table,\n watch: watch,\n unwatch: unwatch\n };\n\n console.log(\"[uniappx-keymap] console snippet ready. Try __UNIAPPX_KEYMAP__.table() or __UNIAPPX_KEYMAP__.watch().\");\n})();\n`;\n}\n"],"mappings":";;AAWA,SAAS,aAAa,QAAqC;CACzD,MAAM,aAAyB,EAAE;AACjC,MAAK,MAAM,QAAQ,OAAO,OAAO,OAAO,MAAM,CAC5C,YAAW,KAAK,QAAQ,KAAK,KAAK,KAAK,UAAU;EAC/C,KAAK,KAAK;EACV,OAAO,KAAK,cAAc,KAAK,iBAAiB,KAAK,qBAAqB;EAC1E,MAAM,KAAK;EACX,YAAY,KAAK;EAClB,EAAE;AAEL,QAAO;;AAGT,SAAgB,qBAAqB,QAAiC;AAEpE,QAAO;iBADM,KAAK,UAAU,aAAa,OAAO,EAAE,MAAM,EAAE,CAEtC"}
|