cap-copilot-widget 0.1.6 → 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/postinstall.js CHANGED
@@ -23,99 +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
- process.exit(0);
45
- }
46
-
47
- const staticDir = path.dirname(htmlPath);
48
-
49
- const bundleSrc = path.join(__dirname, "dist", "btp-copilot.js");
50
- const bundleDest = path.join(staticDir, "btp-copilot.js");
51
-
52
- if (!fs.existsSync(bundleSrc)) {
53
- 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.");
54
- process.exit(0);
55
- }
56
26
 
57
- try {
58
- fs.copyFileSync(bundleSrc, bundleDest);
59
- } catch (e) {
60
- console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not copy bundle to ${path.relative(appRoot, bundleDest)}: ${e.message}`);
61
- process.exit(0);
62
- }
27
+ const htmlPaths = [];
63
28
 
64
- let html;
29
+ const appDir = path.join(appRoot, "app");
65
30
  try {
66
- html = fs.readFileSync(htmlPath, "utf8");
67
- } catch (e) {
68
- console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not read ${path.relative(appRoot, htmlPath)}: ${e.message}`);
69
- process.exit(0);
70
- }
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 */ }
71
39
 
72
- const alreadyHasScript = html.includes("btp-copilot.js");
73
- const alreadyHasElement = html.includes("<btp-copilot");
74
40
 
75
- if (alreadyHasScript && alreadyHasElement) {
76
- console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m \u2714 Widget bundle updated in ${path.relative(appRoot, bundleDest)}`);
77
- process.exit(0);
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
+ }
78
46
  }
79
47
 
48
+ if (htmlPaths.length === 0) process.exit(0);
49
+
80
50
  let appId = "my-app";
81
51
  let appName = "My App";
82
52
  try {
83
53
  const pkg = JSON.parse(fs.readFileSync(path.join(appRoot, "package.json"), "utf8"));
84
- appId = (pkg.name ?? "my-app").replace(/[^a-zA-Z0-9_-]/g, "-");
85
- appName = pkg.description ?? pkg.name ?? "My App";
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";
86
58
  } catch { /* ignore */ }
87
59
 
88
- if (!alreadyHasScript) {
89
- const scriptTag =
90
- ` <!-- injected by cap-copilot-widget -->\n` +
91
- ` <script src="/btp-copilot.js" defer></script>`;
92
- html = html.replace("</head>", `${scriptTag}\n</head>`);
93
- }
94
60
 
95
- if (!alreadyHasElement) {
96
- const widgetElement = [
97
- ` <!-- injected by cap-copilot-widget -->`,
98
- ` <btp-copilot`,
99
- ` app-id="${appId}"`,
100
- ` app-name="${appName}"`,
101
- ` position="bottom-right"`,
102
- ` theme="auto">`,
103
- ` </btp-copilot>`,
104
- ].join("\n");
105
-
106
- if (html.includes("</body>")) {
107
- html = html.replace("</body>", `${widgetElement}\n</body>`);
108
- } else {
109
- html += `\n${widgetElement}\n`;
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");
67
+
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;
110
84
  }
111
- }
112
85
 
113
- try {
114
- fs.writeFileSync(htmlPath, html, "utf8");
115
- console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m \u2714 Copied widget bundle \u2192 ${path.relative(appRoot, bundleDest)}`);
116
- console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m \u2714 Injected <btp-copilot> into ${path.relative(appRoot, htmlPath)}`);
117
- console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m Chatbot URL default: http://localhost:5173`);
118
- console.log(`\x1b[36m[cap-copilot-widget]\x1b[0m Override for production: set iframe-url attribute on <btp-copilot>`);
119
- } catch (e) {
120
- console.warn(`\x1b[33m[cap-copilot-widget]\x1b[0m Warning: Could not write ${path.relative(appRoot, htmlPath)}: ${e.message}`);
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
+ }
121
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).`);