botversion-sdk 1.0.5 → 1.1.6
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/bin/init.js +3 -3
- package/cli/generator.js +3 -3
- package/cli/writer.js +1 -1
- package/client.js +38 -223
- package/index.js +285 -211
- package/interceptor.js +451 -118
- package/package.json +4 -3
- package/scanner.js +1281 -100
package/index.js
CHANGED
|
@@ -1,10 +1,266 @@
|
|
|
1
|
-
// botversion-sdk/index.js
|
|
2
1
|
"use strict";
|
|
3
2
|
|
|
4
3
|
var scanner = require("./scanner");
|
|
5
4
|
var interceptor = require("./interceptor");
|
|
6
5
|
var BotVersionClient = require("./client");
|
|
7
6
|
|
|
7
|
+
// ── Framework auto-detection ─────────────────────────────────────────────────
|
|
8
|
+
// Reads package.json from the customer's codebase and figures out
|
|
9
|
+
// which backend and frontend frameworks they are using.
|
|
10
|
+
function detectFrameworks(cwd) {
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const path = require("path");
|
|
13
|
+
|
|
14
|
+
const result = {
|
|
15
|
+
backend: "unknown",
|
|
16
|
+
frontend: "unknown",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
let pkg = {};
|
|
20
|
+
try {
|
|
21
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
22
|
+
if (fs.existsSync(pkgPath)) {
|
|
23
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
24
|
+
}
|
|
25
|
+
} catch {
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const deps = Object.assign(
|
|
30
|
+
{},
|
|
31
|
+
pkg.dependencies || {},
|
|
32
|
+
pkg.devDependencies || {},
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// ── Backend detection ──────────────────────────────────────────────────────
|
|
36
|
+
if (deps["@nestjs/core"]) {
|
|
37
|
+
result.backend = "nestjs";
|
|
38
|
+
} else if (deps["fastify"]) {
|
|
39
|
+
result.backend = "fastify";
|
|
40
|
+
} else if (deps["@adonisjs/core"]) {
|
|
41
|
+
result.backend = "adonis";
|
|
42
|
+
} else if (deps["@hapi/hapi"] || deps["hapi"]) {
|
|
43
|
+
result.backend = "hapi";
|
|
44
|
+
} else if (deps["koa"]) {
|
|
45
|
+
result.backend = "koa";
|
|
46
|
+
} else if (deps["next"]) {
|
|
47
|
+
result.backend = "nextjs";
|
|
48
|
+
} else if (deps["express"]) {
|
|
49
|
+
result.backend = "express";
|
|
50
|
+
} else if (deps["@remix-run/node"] || deps["@remix-run/serve"]) {
|
|
51
|
+
result.backend = "remix";
|
|
52
|
+
} else if (deps["nuxt"] || deps["nuxt3"] || deps["@nuxt/core"]) {
|
|
53
|
+
result.backend = "nuxt";
|
|
54
|
+
} else if (deps["@sveltejs/kit"]) {
|
|
55
|
+
result.backend = "sveltekit";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ── Frontend detection ─────────────────────────────────────────────────────
|
|
59
|
+
if (deps["next"]) {
|
|
60
|
+
result.frontend = "nextjs";
|
|
61
|
+
} else if (deps["nuxt"] || deps["nuxt3"] || deps["@nuxt/core"]) {
|
|
62
|
+
result.frontend = "nuxt";
|
|
63
|
+
} else if (deps["@sveltejs/kit"]) {
|
|
64
|
+
result.frontend = "sveltekit";
|
|
65
|
+
} else if (deps["@remix-run/react"]) {
|
|
66
|
+
result.frontend = "remix";
|
|
67
|
+
} else if (deps["@tanstack/router"] || deps["@tanstack/react-router"]) {
|
|
68
|
+
result.frontend = "tanstack";
|
|
69
|
+
} else if (deps["vue"] && (deps["vue-router"] || deps["@nuxtjs/router"])) {
|
|
70
|
+
result.frontend = "vue";
|
|
71
|
+
} else if (deps["@angular/core"]) {
|
|
72
|
+
result.frontend = "angular";
|
|
73
|
+
} else if (deps["svelte"]) {
|
|
74
|
+
result.frontend = "svelte";
|
|
75
|
+
} else if (deps["react"] && deps["react-router-dom"]) {
|
|
76
|
+
result.frontend = "react-router";
|
|
77
|
+
} else if (deps["astro"]) {
|
|
78
|
+
result.frontend = "astro";
|
|
79
|
+
} else if (deps["react"]) {
|
|
80
|
+
result.frontend = "react";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ── Run the right backend scanner ────────────────────────────────────────────
|
|
87
|
+
function runBackendScanner(detectedBackend, app, options, cwd) {
|
|
88
|
+
const endpoints = [];
|
|
89
|
+
|
|
90
|
+
switch (detectedBackend) {
|
|
91
|
+
case "express":
|
|
92
|
+
endpoints.push(...scanner.scanExpressRoutes(app, cwd));
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case "nextjs": {
|
|
96
|
+
const fs = require("fs");
|
|
97
|
+
const path = require("path");
|
|
98
|
+
|
|
99
|
+
const possibleAppDirs = [
|
|
100
|
+
path.join(cwd, "app"),
|
|
101
|
+
path.join(cwd, "src", "app"),
|
|
102
|
+
];
|
|
103
|
+
const possiblePagesDirs = [
|
|
104
|
+
path.join(cwd, "pages"),
|
|
105
|
+
path.join(cwd, "src", "pages"),
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
for (const dir of possibleAppDirs) {
|
|
109
|
+
if (fs.existsSync(dir)) {
|
|
110
|
+
endpoints.push(...scanner.scanNextJsAppRoutes(dir));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const dir of possiblePagesDirs) {
|
|
114
|
+
if (fs.existsSync(dir)) {
|
|
115
|
+
endpoints.push(...scanner.scanNextJsRoutes(dir));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
case "fastify":
|
|
122
|
+
endpoints.push(...scanner.scanFastifyRoutes(cwd));
|
|
123
|
+
break;
|
|
124
|
+
|
|
125
|
+
case "nestjs":
|
|
126
|
+
endpoints.push(...scanner.scanNestJsRoutes(cwd));
|
|
127
|
+
break;
|
|
128
|
+
|
|
129
|
+
case "koa":
|
|
130
|
+
endpoints.push(...scanner.scanKoaRoutes(cwd));
|
|
131
|
+
break;
|
|
132
|
+
|
|
133
|
+
case "hapi":
|
|
134
|
+
endpoints.push(...scanner.scanHapiRoutes(cwd));
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
case "adonis":
|
|
138
|
+
endpoints.push(...scanner.scanAdonisRoutes(cwd));
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
case "nuxt":
|
|
142
|
+
endpoints.push(...scanner.scanNuxtServerRoutes(cwd));
|
|
143
|
+
break;
|
|
144
|
+
|
|
145
|
+
case "sveltekit":
|
|
146
|
+
endpoints.push(...scanner.scanSvelteKitServerRoutes(cwd));
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case "remix":
|
|
150
|
+
endpoints.push(...scanner.scanRemixServerRoutes(cwd));
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
default:
|
|
154
|
+
// Unknown backend — try Express as best guess
|
|
155
|
+
if (app) {
|
|
156
|
+
endpoints.push(...scanner.scanExpressRoutes(app, cwd));
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return endpoints;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ── Attach the right runtime interceptor ─────────────────────────────────────
|
|
165
|
+
function attachRuntimeInterceptor(detectedBackend, app, client, options) {
|
|
166
|
+
switch (detectedBackend) {
|
|
167
|
+
case "express":
|
|
168
|
+
interceptor.attachInterceptor(app, client, {
|
|
169
|
+
exclude: options.exclude || [],
|
|
170
|
+
apiPrefix: options.apiPrefix || null,
|
|
171
|
+
debug: options.debug || false,
|
|
172
|
+
});
|
|
173
|
+
break;
|
|
174
|
+
|
|
175
|
+
case "nextjs":
|
|
176
|
+
interceptor.attachNextJsInterceptor(client, {
|
|
177
|
+
exclude: options.exclude || [],
|
|
178
|
+
apiPrefix: options.apiPrefix || "/api",
|
|
179
|
+
debug: options.debug || false,
|
|
180
|
+
});
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case "fastify":
|
|
184
|
+
if (app) {
|
|
185
|
+
interceptor.attachFastifyInterceptor(app, client, {
|
|
186
|
+
exclude: options.exclude || [],
|
|
187
|
+
apiPrefix: options.apiPrefix || null,
|
|
188
|
+
debug: options.debug || false,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
|
|
193
|
+
case "koa":
|
|
194
|
+
if (app) {
|
|
195
|
+
interceptor.attachKoaInterceptor(app, client, {
|
|
196
|
+
exclude: options.exclude || [],
|
|
197
|
+
apiPrefix: options.apiPrefix || null,
|
|
198
|
+
debug: options.debug || false,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case "hapi":
|
|
204
|
+
if (app) {
|
|
205
|
+
interceptor.attachHapiInterceptor(app, client, {
|
|
206
|
+
exclude: options.exclude || [],
|
|
207
|
+
apiPrefix: options.apiPrefix || null,
|
|
208
|
+
debug: options.debug || false,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case "nestjs":
|
|
214
|
+
interceptor.attachNestJsInterceptor(client, {
|
|
215
|
+
exclude: options.exclude || [],
|
|
216
|
+
apiPrefix: options.apiPrefix || "/",
|
|
217
|
+
debug: options.debug || false,
|
|
218
|
+
});
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case "sveltekit":
|
|
222
|
+
interceptor.attachSvelteKitInterceptor(client, {
|
|
223
|
+
exclude: options.exclude || [],
|
|
224
|
+
apiPrefix: options.apiPrefix || "/",
|
|
225
|
+
debug: options.debug || false,
|
|
226
|
+
});
|
|
227
|
+
break;
|
|
228
|
+
|
|
229
|
+
case "nuxt":
|
|
230
|
+
interceptor.attachNuxtInterceptor(client, {
|
|
231
|
+
exclude: options.exclude || [],
|
|
232
|
+
apiPrefix: options.apiPrefix || "/api",
|
|
233
|
+
debug: options.debug || false,
|
|
234
|
+
});
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
case "remix":
|
|
238
|
+
interceptor.attachRemixInterceptor(client, {
|
|
239
|
+
exclude: options.exclude || [],
|
|
240
|
+
apiPrefix: options.apiPrefix || "/",
|
|
241
|
+
debug: options.debug || false,
|
|
242
|
+
});
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case "adonis":
|
|
246
|
+
interceptor.attachAdonisInterceptor(client, {
|
|
247
|
+
exclude: options.exclude || [],
|
|
248
|
+
apiPrefix: options.apiPrefix || "/",
|
|
249
|
+
debug: options.debug || false,
|
|
250
|
+
});
|
|
251
|
+
break;
|
|
252
|
+
|
|
253
|
+
default:
|
|
254
|
+
// Unknown — fall back to Next.js http server patch as best guess
|
|
255
|
+
interceptor.attachNextJsInterceptor(client, {
|
|
256
|
+
exclude: options.exclude || [],
|
|
257
|
+
apiPrefix: options.apiPrefix || "/",
|
|
258
|
+
debug: options.debug || false,
|
|
259
|
+
});
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
8
264
|
var BotVersion = {
|
|
9
265
|
_client: null,
|
|
10
266
|
_initialized: false,
|
|
@@ -26,22 +282,14 @@ var BotVersion = {
|
|
|
26
282
|
app = null;
|
|
27
283
|
}
|
|
28
284
|
|
|
29
|
-
if (!options.apiKey) {
|
|
30
|
-
console.error("[BotVersion SDK] ❌ apiKey is required.");
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
285
|
// Restore from global if module was re-imported after hot reload
|
|
35
286
|
if (global._botVersionClient) {
|
|
36
287
|
this._client = global._botVersionClient;
|
|
37
288
|
this._options = global._botVersionOptions;
|
|
38
289
|
this._initialized = true;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (this._initialized) {
|
|
44
|
-
console.warn("[BotVersion SDK] Already initialized — skipping");
|
|
290
|
+
const savedOptions = global._botVersionOptions || {};
|
|
291
|
+
const savedFramework = global._botVersionFramework || "nextjs";
|
|
292
|
+
attachRuntimeInterceptor(savedFramework, app, this._client, savedOptions);
|
|
45
293
|
return;
|
|
46
294
|
}
|
|
47
295
|
|
|
@@ -51,7 +299,7 @@ var BotVersion = {
|
|
|
51
299
|
|
|
52
300
|
this._client = new BotVersionClient({
|
|
53
301
|
apiKey: options.apiKey,
|
|
54
|
-
platformUrl: options.platformUrl || "
|
|
302
|
+
platformUrl: options.platformUrl || "https://botversion.com",
|
|
55
303
|
debug: options.debug || false,
|
|
56
304
|
timeout: options.timeout || 30000,
|
|
57
305
|
});
|
|
@@ -60,185 +308,44 @@ var BotVersion = {
|
|
|
60
308
|
global._botVersionOptions = options;
|
|
61
309
|
|
|
62
310
|
var self = this;
|
|
311
|
+
var cwd = options.cwd || process.cwd();
|
|
63
312
|
var debug = options.debug || false;
|
|
64
313
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (app) {
|
|
68
|
-
console.log("[BotVersion SDK] Mode: Express");
|
|
69
|
-
} else {
|
|
70
|
-
console.log("[BotVersion SDK] Mode: Next.js (file-based routing)");
|
|
71
|
-
}
|
|
72
|
-
}
|
|
314
|
+
// ── Auto-detect frameworks ───────────────────────────────────────────────
|
|
315
|
+
var detected = detectFrameworks(cwd);
|
|
73
316
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!frameworkCheck.supported) {
|
|
78
|
-
console.error(
|
|
79
|
-
"[BotVersion SDK] ❌ Unsupported framework:",
|
|
80
|
-
frameworkCheck.name,
|
|
81
|
-
);
|
|
82
|
-
console.error(
|
|
83
|
-
"[BotVersion SDK] ❌ Currently supports Express and Next.js only.",
|
|
84
|
-
);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (debug) {
|
|
88
|
-
console.log(
|
|
89
|
-
"[BotVersion SDK] ✅ Framework detected:",
|
|
90
|
-
frameworkCheck.name,
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
317
|
+
// Allow manual override from options
|
|
318
|
+
var detectedBackend = options.framework || detected.backend;
|
|
319
|
+
var detectedFrontend = options.frontendFramework || detected.frontend;
|
|
94
320
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
apiPrefix: options.apiPrefix || null,
|
|
100
|
-
debug: debug,
|
|
101
|
-
});
|
|
102
|
-
if (debug) {
|
|
103
|
-
console.log("[BotVersion SDK] ✅ Runtime interceptor attached");
|
|
104
|
-
}
|
|
105
|
-
} else if (!app) {
|
|
106
|
-
if (debug) {
|
|
107
|
-
console.log(
|
|
108
|
-
"[BotVersion SDK] ℹ Runtime interceptor skipped — Next.js mode uses file scanning only",
|
|
109
|
-
);
|
|
110
|
-
}
|
|
321
|
+
global._botVersionFramework = detectedBackend;
|
|
322
|
+
|
|
323
|
+
if (debug) {
|
|
324
|
+
// Detected: detectedBackend, detectedFrontend
|
|
111
325
|
}
|
|
112
326
|
|
|
327
|
+
// ── Attach runtime interceptor ───────────────────────────────────────────
|
|
328
|
+
attachRuntimeInterceptor(detectedBackend, app, self._client, options);
|
|
329
|
+
|
|
113
330
|
// ── Static scan ──────────────────────────────────────────────────────────
|
|
114
331
|
setTimeout(function () {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// Express scan
|
|
118
|
-
// Express scan
|
|
119
|
-
if (app) {
|
|
120
|
-
console.log("[BotVersion SDK] Scanning Express routes...");
|
|
121
|
-
var cwd = options.cwd || process.cwd();
|
|
122
|
-
endpoints = scanner.scanExpressRoutes(app, cwd);
|
|
123
|
-
console.log(
|
|
124
|
-
"[BotVersion SDK] Found",
|
|
125
|
-
endpoints.length,
|
|
126
|
-
"Express routes",
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
if (endpoints.length === 0) {
|
|
130
|
-
console.warn("[BotVersion SDK] ⚠ No endpoints found.");
|
|
131
|
-
console.warn(
|
|
132
|
-
"[BotVersion SDK] ⚠ Make sure routes are defined BEFORE BotVersion.init()",
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Next.js scan
|
|
138
|
-
// Next.js scan — auto detect all possible structures
|
|
139
|
-
if (!app) {
|
|
140
|
-
const fs = require("fs");
|
|
141
|
-
const path = require("path");
|
|
142
|
-
const cwd = process.cwd();
|
|
143
|
-
|
|
144
|
-
const possibleAppDirs = [
|
|
145
|
-
path.join(cwd, "app"),
|
|
146
|
-
path.join(cwd, "src", "app"),
|
|
147
|
-
];
|
|
148
|
-
|
|
149
|
-
const possiblePagesDirs = [
|
|
150
|
-
path.join(cwd, "pages"),
|
|
151
|
-
path.join(cwd, "src", "pages"),
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
for (const dir of possibleAppDirs) {
|
|
155
|
-
if (fs.existsSync(dir)) {
|
|
156
|
-
console.log("[BotVersion SDK] Scanning App Router routes at:", dir);
|
|
157
|
-
const routes = scanner.scanNextJsAppRoutes(dir);
|
|
158
|
-
endpoints = endpoints.concat(routes);
|
|
159
|
-
console.log(
|
|
160
|
-
"[BotVersion SDK] Found",
|
|
161
|
-
routes.length,
|
|
162
|
-
"App Router routes",
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
for (const dir of possiblePagesDirs) {
|
|
168
|
-
if (fs.existsSync(dir)) {
|
|
169
|
-
console.log(
|
|
170
|
-
"[BotVersion SDK] Scanning Pages Router routes at:",
|
|
171
|
-
dir,
|
|
172
|
-
);
|
|
173
|
-
const routes = scanner.scanNextJsRoutes(dir);
|
|
174
|
-
endpoints = endpoints.concat(routes);
|
|
175
|
-
console.log(
|
|
176
|
-
"[BotVersion SDK] Found",
|
|
177
|
-
routes.length,
|
|
178
|
-
"Pages Router routes",
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
332
|
+
// Run backend scanner
|
|
333
|
+
var endpoints = runBackendScanner(detectedBackend, app, options, cwd);
|
|
183
334
|
|
|
184
|
-
//
|
|
185
|
-
// Neither Express nor Next.js routes found
|
|
186
|
-
if (!app && endpoints.length === 0) {
|
|
187
|
-
console.error(
|
|
188
|
-
"[BotVersion SDK] ❌ No routes found. Make sure your app/api or pages/api folder exists.",
|
|
189
|
-
);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Send to platform
|
|
335
|
+
// Send endpoints to platform
|
|
194
336
|
if (endpoints.length > 0) {
|
|
195
|
-
|
|
196
|
-
"[BotVersion SDK] Sending",
|
|
197
|
-
endpoints.length,
|
|
198
|
-
"endpoints to platform...",
|
|
199
|
-
);
|
|
200
|
-
self._client
|
|
201
|
-
.registerEndpoints(endpoints)
|
|
202
|
-
.then(function () {
|
|
203
|
-
console.log(
|
|
204
|
-
"[BotVersion SDK] ✅ Endpoints queued —",
|
|
205
|
-
endpoints.length,
|
|
206
|
-
"endpoints will be sent shortly",
|
|
207
|
-
);
|
|
208
|
-
})
|
|
209
|
-
.catch(function (err) {
|
|
210
|
-
console.error(
|
|
211
|
-
"[BotVersion SDK] ❌ Failed to register endpoints:",
|
|
212
|
-
err.message,
|
|
213
|
-
);
|
|
214
|
-
});
|
|
337
|
+
self._client.registerEndpoints(endpoints);
|
|
215
338
|
}
|
|
216
339
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
340
|
+
// Run frontend route scanner
|
|
341
|
+
var routePatterns = scanner.scanFrontendRoutes(cwd);
|
|
342
|
+
|
|
220
343
|
if (routePatterns.length > 0) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"frontend route patterns",
|
|
225
|
-
);
|
|
226
|
-
self._client
|
|
227
|
-
.registerRoutePatterns(routePatterns)
|
|
228
|
-
.then(function () {
|
|
229
|
-
console.log("[BotVersion SDK] ✅ Route patterns registered");
|
|
230
|
-
})
|
|
231
|
-
.catch(function (err) {
|
|
232
|
-
console.error(
|
|
233
|
-
"[BotVersion SDK] ❌ Failed to register route patterns:",
|
|
234
|
-
err.message,
|
|
235
|
-
);
|
|
236
|
-
});
|
|
344
|
+
self._client.registerRoutePatterns(routePatterns).catch(function () {
|
|
345
|
+
// silently ignore — non-critical
|
|
346
|
+
});
|
|
237
347
|
}
|
|
238
|
-
|
|
239
|
-
self._client.connect();
|
|
240
|
-
console.log("[BotVersion SDK] ✅ Initialization complete");
|
|
241
|
-
}, 500);
|
|
348
|
+
}, 3000);
|
|
242
349
|
},
|
|
243
350
|
|
|
244
351
|
getEndpoints: function () {
|
|
@@ -270,36 +377,3 @@ module.exports.default = BotVersion;
|
|
|
270
377
|
module.exports.init = BotVersion.init;
|
|
271
378
|
module.exports.getEndpoints = BotVersion.getEndpoints;
|
|
272
379
|
module.exports.registerEndpoint = BotVersion.registerEndpoint;
|
|
273
|
-
|
|
274
|
-
// ── Framework detection ──────────────────────────────────────────────────────
|
|
275
|
-
function detectFramework(app) {
|
|
276
|
-
if (!app) return { supported: false, name: "unknown (no app passed)" };
|
|
277
|
-
|
|
278
|
-
var isExpress =
|
|
279
|
-
typeof app.use === "function" &&
|
|
280
|
-
typeof app.get === "function" &&
|
|
281
|
-
typeof app.post === "function" &&
|
|
282
|
-
(app._router !== undefined ||
|
|
283
|
-
app.stack !== undefined ||
|
|
284
|
-
app.lazyrouter !== undefined);
|
|
285
|
-
|
|
286
|
-
if (isExpress) return { supported: true, name: "Express" };
|
|
287
|
-
|
|
288
|
-
if (typeof app.addHook === "function" && typeof app.route === "function") {
|
|
289
|
-
return { supported: false, name: "Fastify" };
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
typeof app.use === "function" &&
|
|
294
|
-
app.context !== undefined &&
|
|
295
|
-
typeof app.get !== "function"
|
|
296
|
-
) {
|
|
297
|
-
return { supported: false, name: "Koa" };
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (typeof app.route === "function" && typeof app.start === "function") {
|
|
301
|
-
return { supported: false, name: "Hapi" };
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return { supported: false, name: "unknown" };
|
|
305
|
-
}
|