apiblaze 0.21.29 → 0.21.31
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/index.js +118 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
|
|
|
34
34
|
var version;
|
|
35
35
|
var init_package = __esm({
|
|
36
36
|
"package.json"() {
|
|
37
|
-
version = "0.21.
|
|
37
|
+
version = "0.21.31";
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
|
|
@@ -7521,6 +7521,7 @@ __export(demo_exports, {
|
|
|
7521
7521
|
DEMO_GINO_ADMIN_EMAIL: () => DEMO_GINO_ADMIN_EMAIL,
|
|
7522
7522
|
DEMO_RPS: () => DEMO_RPS,
|
|
7523
7523
|
demoName: () => demoName,
|
|
7524
|
+
isDemoProcess: () => isDemoProcess,
|
|
7524
7525
|
routesOf: () => routesOf,
|
|
7525
7526
|
runDemo: () => runDemo,
|
|
7526
7527
|
runDemoLogs: () => runDemoLogs,
|
|
@@ -7602,12 +7603,40 @@ function appCtl(dir, arg) {
|
|
|
7602
7603
|
const r = (0, import_child_process4.spawnSync)(process.execPath, [import_path5.default.join(dir, "start.js"), arg], { cwd: dir, stdio: "ignore", timeout: 15e3 });
|
|
7603
7604
|
return r.status === 0;
|
|
7604
7605
|
}
|
|
7606
|
+
function isDemoProcess(args) {
|
|
7607
|
+
return /[\\/](apiblaze|mcpblaze)-demo[\\/]start\.js(\s|$)/.test(args) || /\sdemo --serve\s/.test(args);
|
|
7608
|
+
}
|
|
7609
|
+
function demoProcesses() {
|
|
7610
|
+
if (process.platform === "win32") return [];
|
|
7611
|
+
const r = (0, import_child_process4.spawnSync)("ps", ["-Ao", "pid=,args="], { encoding: "utf8" });
|
|
7612
|
+
if (r.status !== 0 || !r.stdout) return [];
|
|
7613
|
+
const out = [];
|
|
7614
|
+
for (const line of r.stdout.split("\n")) {
|
|
7615
|
+
const m = /^\s*(\d+)\s+(.*)$/.exec(line);
|
|
7616
|
+
if (m && Number(m[1]) !== process.pid && isDemoProcess(m[2])) out.push(Number(m[1]));
|
|
7617
|
+
}
|
|
7618
|
+
return out;
|
|
7619
|
+
}
|
|
7605
7620
|
async function stopDemos() {
|
|
7606
7621
|
const dirs = [...new Set(readRegistry().map((r) => r.dir))];
|
|
7607
7622
|
const n = await stopTunnels();
|
|
7608
7623
|
for (const d of dirs) appCtl(d, "--stop");
|
|
7609
7624
|
writeRegistry([]);
|
|
7610
|
-
|
|
7625
|
+
const left = demoProcesses();
|
|
7626
|
+
for (const pid of left) {
|
|
7627
|
+
try {
|
|
7628
|
+
process.kill(pid, "SIGTERM");
|
|
7629
|
+
} catch {
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
for (let i = 0; i < 40 && left.some(alive); i++) await new Promise((r) => setTimeout(r, 100));
|
|
7633
|
+
for (const pid of left) if (alive(pid)) {
|
|
7634
|
+
try {
|
|
7635
|
+
process.kill(pid, "SIGKILL");
|
|
7636
|
+
} catch {
|
|
7637
|
+
}
|
|
7638
|
+
}
|
|
7639
|
+
return n + left.length;
|
|
7611
7640
|
}
|
|
7612
7641
|
function writeApp(dir) {
|
|
7613
7642
|
import_fs6.default.mkdirSync(dir, { recursive: true });
|
|
@@ -9205,6 +9234,80 @@ function fromNode(dir, out) {
|
|
|
9205
9234
|
out.configuredPort = portFromScripts(scripts);
|
|
9206
9235
|
out.start = scripts.dev ? "npm run dev" : scripts.start ? "npm start" : void 0;
|
|
9207
9236
|
}
|
|
9237
|
+
var ENTRY_FILES = [
|
|
9238
|
+
"server.js",
|
|
9239
|
+
"app.js",
|
|
9240
|
+
"index.js",
|
|
9241
|
+
"main.js",
|
|
9242
|
+
"server.mjs",
|
|
9243
|
+
"app.mjs",
|
|
9244
|
+
"index.mjs",
|
|
9245
|
+
"server.cjs",
|
|
9246
|
+
"server.ts",
|
|
9247
|
+
"app.ts",
|
|
9248
|
+
"index.ts",
|
|
9249
|
+
"main.ts",
|
|
9250
|
+
"src/server.ts",
|
|
9251
|
+
"src/index.ts",
|
|
9252
|
+
"src/app.ts",
|
|
9253
|
+
"src/main.ts",
|
|
9254
|
+
"src/server.js",
|
|
9255
|
+
"src/index.js",
|
|
9256
|
+
"src/app.js",
|
|
9257
|
+
"main.py",
|
|
9258
|
+
"app.py",
|
|
9259
|
+
"server.py",
|
|
9260
|
+
"main.go",
|
|
9261
|
+
"server.go"
|
|
9262
|
+
];
|
|
9263
|
+
var NODE_MODULE_SERVERS = [
|
|
9264
|
+
[/\b(?:require\(\s*|from\s+)['"]express['"]/, "Express"],
|
|
9265
|
+
[/\b(?:require\(\s*|from\s+)['"]fastify['"]/, "Fastify"],
|
|
9266
|
+
[/\b(?:require\(\s*|from\s+)['"]koa['"]/, "Koa"],
|
|
9267
|
+
[/\b(?:require\(\s*|from\s+)['"]hono['"]/, "Hono"],
|
|
9268
|
+
[/\b(?:require\(\s*|from\s+)['"](?:node:)?https?['"]/, "a Node server"]
|
|
9269
|
+
];
|
|
9270
|
+
function portInSource(text) {
|
|
9271
|
+
const m = /\.listen\(\s*(\d{2,5})\b/.exec(text) ?? /\bPORT\b[^\n]{0,40}?(?:\|\||\?\?|or)\s*['"]?(\d{2,5})\b/.exec(text) ?? /\bport\s*[:=]\s*(\d{2,5})\b/.exec(text) ?? /ListenAndServe\(\s*"[^":]*:(\d{2,5})"/.exec(text) ?? /\.run\([^)]*port\s*=\s*(\d{2,5})/.exec(text);
|
|
9272
|
+
return m ? Number(m[1]) : void 0;
|
|
9273
|
+
}
|
|
9274
|
+
function fromEntryFiles(dir, out) {
|
|
9275
|
+
for (const rel of ENTRY_FILES) {
|
|
9276
|
+
const text = readText(import_path4.default.join(dir, rel));
|
|
9277
|
+
if (!text) continue;
|
|
9278
|
+
let fw;
|
|
9279
|
+
let def;
|
|
9280
|
+
if (/\.(c|m)?[jt]s$/.test(rel)) {
|
|
9281
|
+
if (!/\.listen\(|createServer\(|\bserve\(|export default\s+app\b/.test(text)) continue;
|
|
9282
|
+
fw = NODE_MODULE_SERVERS.find(([re]) => re.test(text))?.[1] ?? "a Node server";
|
|
9283
|
+
def = 3e3;
|
|
9284
|
+
} else if (rel.endsWith(".py")) {
|
|
9285
|
+
if (/\bFastAPI\(/.test(text)) {
|
|
9286
|
+
fw = "FastAPI";
|
|
9287
|
+
def = 8e3;
|
|
9288
|
+
} else if (/\bFlask\(/.test(text)) {
|
|
9289
|
+
fw = "Flask";
|
|
9290
|
+
def = 5e3;
|
|
9291
|
+
} else if (/HTTPServer\(|http\.server/.test(text)) {
|
|
9292
|
+
fw = "a Python server";
|
|
9293
|
+
def = 8e3;
|
|
9294
|
+
} else continue;
|
|
9295
|
+
} else if (rel.endsWith(".go")) {
|
|
9296
|
+
if (!/ListenAndServe\(|\.Run\(|\.Start\(|\.Listen\(/.test(text)) continue;
|
|
9297
|
+
fw = GO_SERVERS.find(([re]) => re.test(text))?.[1] ?? "a Go server";
|
|
9298
|
+
def = 8080;
|
|
9299
|
+
}
|
|
9300
|
+
if (!fw) continue;
|
|
9301
|
+
if (!out.framework) {
|
|
9302
|
+
out.framework = fw;
|
|
9303
|
+
out.source = rel;
|
|
9304
|
+
out.defaultPort = def;
|
|
9305
|
+
}
|
|
9306
|
+
if (!out.configuredPort) out.configuredPort = portInSource(text);
|
|
9307
|
+
if (!out.start && rel.endsWith(".js")) out.start = `node ${rel}`;
|
|
9308
|
+
return;
|
|
9309
|
+
}
|
|
9310
|
+
}
|
|
9208
9311
|
function fromPython(dir, out) {
|
|
9209
9312
|
for (const f of ["requirements.txt", "pyproject.toml", "Pipfile"]) {
|
|
9210
9313
|
const text = readText(import_path4.default.join(dir, f));
|
|
@@ -9278,6 +9381,7 @@ async function detectBackend(dir, opts = {}) {
|
|
|
9278
9381
|
fromNode(dir, out);
|
|
9279
9382
|
if (!out.framework) fromPython(dir, out);
|
|
9280
9383
|
if (!out.framework) fromOthers(dir, out);
|
|
9384
|
+
if (!out.frontendOnly && (!out.framework || !out.configuredPort)) fromEntryFiles(dir, out);
|
|
9281
9385
|
const spec2 = findSpecFile(dir);
|
|
9282
9386
|
if (spec2) {
|
|
9283
9387
|
out.specFile = spec2.file;
|
|
@@ -9340,7 +9444,7 @@ function folderReport(f, opts = {}) {
|
|
|
9340
9444
|
// A person may know what that is; an agent would only be distracted by it.
|
|
9341
9445
|
opts.forPerson && f.strayPorts?.length ? ` Something answers on localhost:${f.strayPorts[0]}, but nothing in this folder points at it.` : ""
|
|
9342
9446
|
].join("");
|
|
9343
|
-
return { lines: [`No backend
|
|
9447
|
+
return { lines: [`No backend in this folder: no server framework in the project files and no OpenAPI spec.${extra}`], question: demoQuestion, ownApi: false };
|
|
9344
9448
|
}
|
|
9345
9449
|
const port = backendPort(f);
|
|
9346
9450
|
const spec2 = f.specFile ? `Spec: ${f.specFile}.` : f.specUrl ? `It serves its spec at ${f.specUrl}.` : "No OpenAPI spec yet.";
|
|
@@ -9885,11 +9989,19 @@ async function runForPerson(found) {
|
|
|
9885
9989
|
return;
|
|
9886
9990
|
}
|
|
9887
9991
|
if (report.ownApi) {
|
|
9888
|
-
|
|
9889
|
-
|
|
9992
|
+
const args = ["dev", "--port", String(port ?? 3e3), ...found.specFile ? ["--openapi", found.specFile] : []];
|
|
9993
|
+
const startHint = found.start ? `, once you start it (${found.start})` : ", once it runs";
|
|
9994
|
+
if (!await ask2(` ${import_chalk25.default.bold("?")} Put it behind ${P} now? It reaches your app on port ${port ?? 3e3}${startHint}. ${import_chalk25.default.dim("(Y/n)")} `)) {
|
|
9995
|
+
console.log(` Any time: ${import_chalk25.default.cyan(`${run2} ${args.join(" ")}`)}`);
|
|
9996
|
+
return;
|
|
9997
|
+
}
|
|
9998
|
+
console.log(import_chalk25.default.dim(` $ ${run2} ${args.join(" ")}`));
|
|
9999
|
+
const { spawnSync: spawnSync4 } = await import("child_process");
|
|
10000
|
+
const r = spawnSync4(process.execPath, [process.argv[1], ...args], { stdio: "inherit" });
|
|
10001
|
+
process.exitCode = r.status ?? 0;
|
|
9890
10002
|
return;
|
|
9891
10003
|
}
|
|
9892
|
-
if (!await ask2(` ${import_chalk25.default.bold("?")}
|
|
10004
|
+
if (!await ask2(` ${import_chalk25.default.bold("?")} Create a demo app to try out ${P}? ${import_chalk25.default.dim("(Y/n)")} `)) {
|
|
9893
10005
|
console.log(` Your own app, when it runs: ${import_chalk25.default.cyan(`${run2} dev --port <port>`)}`);
|
|
9894
10006
|
return;
|
|
9895
10007
|
}
|