cap-copilot-widget 0.1.7 → 0.1.8
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/package.json +1 -1
- package/postinstall.js +72 -95
package/package.json
CHANGED
package/postinstall.js
CHANGED
|
@@ -23,116 +23,93 @@ function findAppRoot() {
|
|
|
23
23
|
const appRoot = findAppRoot();
|
|
24
24
|
if (!appRoot) process.exit(0);
|
|
25
25
|
|
|
26
|
-
const HTML_CANDIDATES = [
|
|
27
|
-
"index.html",
|
|
28
|
-
"app/index.html",
|
|
29
|
-
"public/index.html",
|
|
30
|
-
"webapp/index.html",
|
|
31
|
-
"src/index.html",
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
let htmlPath = null;
|
|
35
|
-
for (const rel of HTML_CANDIDATES) {
|
|
36
|
-
const candidate = path.join(appRoot, rel);
|
|
37
|
-
if (fs.existsSync(candidate)) {
|
|
38
|
-
htmlPath = candidate;
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!htmlPath) {
|
|
44
|
-
try {
|
|
45
|
-
const appDir = path.join(appRoot, "app");
|
|
46
|
-
if (fs.existsSync(appDir)) {
|
|
47
|
-
for (const entry of fs.readdirSync(appDir, { withFileTypes: true })) {
|
|
48
|
-
if (!entry.isDirectory()) continue;
|
|
49
|
-
const candidate = path.join(appDir, entry.name, "webapp", "index.html");
|
|
50
|
-
if (fs.existsSync(candidate)) {
|
|
51
|
-
htmlPath = candidate;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
} catch { /* ignore */ }
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (!htmlPath) {
|
|
60
|
-
process.exit(0);
|
|
61
|
-
}
|
|
62
26
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const bundleSrc = path.join(__dirname, "dist", "btp-copilot.js");
|
|
66
|
-
const bundleDest = path.join(staticDir, "btp-copilot.js");
|
|
67
|
-
|
|
68
|
-
if (!fs.existsSync(bundleSrc)) {
|
|
69
|
-
console.warn("\x1b[33m[cap-copilot-widget]\x1b[0m Warning: dist/btp-copilot.js not found — run `npm run build` in the widget package first.");
|
|
70
|
-
process.exit(0);
|
|
71
|
-
}
|
|
27
|
+
const htmlPaths = [];
|
|
72
28
|
|
|
29
|
+
const appDir = path.join(appRoot, "app");
|
|
73
30
|
try {
|
|
74
|
-
fs.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
html = fs.readFileSync(htmlPath, "utf8");
|
|
83
|
-
} catch (e) {
|
|
84
|
-
console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not read ${path.relative(appRoot, htmlPath)}: ${e.message}`);
|
|
85
|
-
process.exit(0);
|
|
86
|
-
}
|
|
31
|
+
if (fs.existsSync(appDir)) {
|
|
32
|
+
for (const entry of fs.readdirSync(appDir, { withFileTypes: true })) {
|
|
33
|
+
if (!entry.isDirectory()) continue;
|
|
34
|
+
const candidate = path.join(appDir, entry.name, "webapp", "index.html");
|
|
35
|
+
if (fs.existsSync(candidate)) htmlPaths.push(candidate);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} catch { /* ignore */ }
|
|
87
39
|
|
|
88
|
-
const alreadyHasScript = html.includes("btp-copilot.js");
|
|
89
|
-
const alreadyHasElement = html.includes("<btp-copilot");
|
|
90
40
|
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
41
|
+
if (htmlPaths.length === 0) {
|
|
42
|
+
for (const rel of ["webapp/index.html", "public/index.html", "src/index.html", "index.html"]) {
|
|
43
|
+
const candidate = path.join(appRoot, rel);
|
|
44
|
+
if (fs.existsSync(candidate)) { htmlPaths.push(candidate); break; }
|
|
45
|
+
}
|
|
94
46
|
}
|
|
95
47
|
|
|
48
|
+
if (htmlPaths.length === 0) process.exit(0);
|
|
49
|
+
|
|
96
50
|
let appId = "my-app";
|
|
97
51
|
let appName = "My App";
|
|
98
52
|
try {
|
|
99
53
|
const pkg = JSON.parse(fs.readFileSync(path.join(appRoot, "package.json"), "utf8"));
|
|
100
|
-
|
|
101
|
-
|
|
54
|
+
const cdsSection = pkg.cds ?? {};
|
|
55
|
+
const btpCfg = cdsSection.requires?.["btp-copilot"] ?? {};
|
|
56
|
+
appId = btpCfg.appId ?? (pkg.name ?? "my-app").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
57
|
+
appName = btpCfg.appName ?? pkg.description ?? pkg.name ?? "My App";
|
|
102
58
|
} catch { /* ignore */ }
|
|
103
59
|
|
|
104
|
-
if (!alreadyHasScript) {
|
|
105
60
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
61
|
+
const SCRIPT_SRC = "/__btp-copilot-widget/btp-copilot.js";
|
|
62
|
+
|
|
63
|
+
const scriptTag = [
|
|
64
|
+
` <!-- injected by cap-copilot-widget -->`,
|
|
65
|
+
` <script src="${SCRIPT_SRC}" defer></script>`,
|
|
66
|
+
].join("\n");
|
|
111
67
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
html =
|
|
125
|
-
}
|
|
126
|
-
|
|
68
|
+
const widgetElement = [
|
|
69
|
+
` <!-- injected by cap-copilot-widget -->`,
|
|
70
|
+
` <btp-copilot`,
|
|
71
|
+
` app-id="${appId}"`,
|
|
72
|
+
` app-name="${appName}"`,
|
|
73
|
+
` position="bottom-right">`,
|
|
74
|
+
` </btp-copilot>`,
|
|
75
|
+
].join("\n");
|
|
76
|
+
|
|
77
|
+
for (const htmlPath of htmlPaths) {
|
|
78
|
+
let html;
|
|
79
|
+
try {
|
|
80
|
+
html = fs.readFileSync(htmlPath, "utf8");
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not read ${path.relative(appRoot, htmlPath)}: ${e.message}`);
|
|
83
|
+
continue;
|
|
127
84
|
}
|
|
128
|
-
}
|
|
129
85
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
86
|
+
const alreadyHasScript = html.includes(SCRIPT_SRC) || html.includes("btp-copilot-widget");
|
|
87
|
+
const alreadyHasElement = html.includes("<btp-copilot");
|
|
88
|
+
|
|
89
|
+
if (alreadyHasScript && alreadyHasElement) {
|
|
90
|
+
console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m \u2714 Already configured: ${path.relative(appRoot, htmlPath)}`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!alreadyHasScript) {
|
|
95
|
+
html = html.replace("</head>", `${scriptTag}\n</head>`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!alreadyHasElement) {
|
|
99
|
+
if (html.includes("</body>")) {
|
|
100
|
+
html = html.replace("</body>", `${widgetElement}\n</body>`);
|
|
101
|
+
} else {
|
|
102
|
+
html += `\n${widgetElement}\n`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
fs.writeFileSync(htmlPath, html, "utf8");
|
|
108
|
+
console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m \u2714 Injected <btp-copilot> into ${path.relative(appRoot, htmlPath)}`);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not write ${path.relative(appRoot, htmlPath)}: ${e.message}`);
|
|
111
|
+
}
|
|
138
112
|
}
|
|
113
|
+
|
|
114
|
+
console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m Widget JS served by CAP at ${SCRIPT_SRC} (no file copies needed).`);
|
|
115
|
+
console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m URLs are auto-configured from the CDS plugin (/__btp-copilot/config).`);
|