jxp 4.1.1 → 5.0.0
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/.env.sample +30 -0
- package/README.md +2 -0
- package/dist/bin/index_audit.d.ts +3 -0
- package/dist/bin/index_audit.d.ts.map +1 -0
- package/dist/bin/index_audit.js +66 -0
- package/dist/bin/index_audit.js.map +1 -0
- package/dist/bin/mcp-stdio-bridge.d.ts +3 -0
- package/dist/bin/mcp-stdio-bridge.d.ts.map +1 -0
- package/dist/bin/mcp-stdio-bridge.js +87 -0
- package/dist/bin/mcp-stdio-bridge.js.map +1 -0
- package/dist/bin/server.d.ts.map +1 -1
- package/dist/bin/server.js +8 -2
- package/dist/bin/server.js.map +1 -1
- package/dist/libs/builtin_models.d.ts +21 -0
- package/dist/libs/builtin_models.d.ts.map +1 -0
- package/dist/libs/builtin_models.js +125 -0
- package/dist/libs/builtin_models.js.map +1 -0
- package/dist/libs/docs-auth.d.ts.map +1 -1
- package/dist/libs/docs-auth.js +6 -2
- package/dist/libs/docs-auth.js.map +1 -1
- package/dist/libs/docs.js +105 -44
- package/dist/libs/docs.js.map +1 -1
- package/dist/libs/groups.js +3 -4
- package/dist/libs/groups.js.map +1 -1
- package/dist/libs/index_diagnostics.d.ts +144 -0
- package/dist/libs/index_diagnostics.d.ts.map +1 -0
- package/dist/libs/index_diagnostics.js +671 -0
- package/dist/libs/index_diagnostics.js.map +1 -0
- package/dist/libs/jxp.d.ts.map +1 -1
- package/dist/libs/jxp.js +97 -331
- package/dist/libs/jxp.js.map +1 -1
- package/dist/libs/load-config.d.ts +2 -0
- package/dist/libs/load-config.d.ts.map +1 -1
- package/dist/libs/load-config.js +10 -0
- package/dist/libs/load-config.js.map +1 -1
- package/dist/libs/login.js +3 -8
- package/dist/libs/login.js.map +1 -1
- package/dist/libs/mcp/auth.d.ts +4 -0
- package/dist/libs/mcp/auth.d.ts.map +1 -0
- package/dist/libs/mcp/auth.js +49 -0
- package/dist/libs/mcp/auth.js.map +1 -0
- package/dist/libs/mcp/config.d.ts +21 -0
- package/dist/libs/mcp/config.d.ts.map +1 -0
- package/dist/libs/mcp/config.js +66 -0
- package/dist/libs/mcp/config.js.map +1 -0
- package/dist/libs/mcp/context.d.ts +5 -0
- package/dist/libs/mcp/context.d.ts.map +1 -0
- package/dist/libs/mcp/context.js +14 -0
- package/dist/libs/mcp/context.js.map +1 -0
- package/dist/libs/mcp/describe.d.ts +13 -0
- package/dist/libs/mcp/describe.d.ts.map +1 -0
- package/dist/libs/mcp/describe.js +36 -0
- package/dist/libs/mcp/describe.js.map +1 -0
- package/dist/libs/mcp/docs_auth.d.ts +5 -0
- package/dist/libs/mcp/docs_auth.d.ts.map +1 -0
- package/dist/libs/mcp/docs_auth.js +36 -0
- package/dist/libs/mcp/docs_auth.js.map +1 -0
- package/dist/libs/mcp/dynamic_import.d.ts +6 -0
- package/dist/libs/mcp/dynamic_import.d.ts.map +1 -0
- package/dist/libs/mcp/dynamic_import.js +12 -0
- package/dist/libs/mcp/dynamic_import.js.map +1 -0
- package/dist/libs/mcp/execute_tool.d.ts +10 -0
- package/dist/libs/mcp/execute_tool.d.ts.map +1 -0
- package/dist/libs/mcp/execute_tool.js +65 -0
- package/dist/libs/mcp/execute_tool.js.map +1 -0
- package/dist/libs/mcp/guides/default.md +67 -0
- package/dist/libs/mcp/guides.d.ts +14 -0
- package/dist/libs/mcp/guides.d.ts.map +1 -0
- package/dist/libs/mcp/guides.js +127 -0
- package/dist/libs/mcp/guides.js.map +1 -0
- package/dist/libs/mcp/model_visibility.d.ts +31 -0
- package/dist/libs/mcp/model_visibility.d.ts.map +1 -0
- package/dist/libs/mcp/model_visibility.js +73 -0
- package/dist/libs/mcp/model_visibility.js.map +1 -0
- package/dist/libs/mcp/mount.d.ts +10 -0
- package/dist/libs/mcp/mount.d.ts.map +1 -0
- package/dist/libs/mcp/mount.js +68 -0
- package/dist/libs/mcp/mount.js.map +1 -0
- package/dist/libs/mcp/read_service.d.ts +23 -0
- package/dist/libs/mcp/read_service.d.ts.map +1 -0
- package/dist/libs/mcp/read_service.js +141 -0
- package/dist/libs/mcp/read_service.js.map +1 -0
- package/dist/libs/mcp/server.d.ts +23 -0
- package/dist/libs/mcp/server.d.ts.map +1 -0
- package/dist/libs/mcp/server.js +111 -0
- package/dist/libs/mcp/server.js.map +1 -0
- package/dist/libs/parse_byte_size.d.ts +10 -0
- package/dist/libs/parse_byte_size.d.ts.map +1 -0
- package/dist/libs/parse_byte_size.js +80 -0
- package/dist/libs/parse_byte_size.js.map +1 -0
- package/dist/libs/query_limits.js +99 -13
- package/dist/libs/query_limits.js.map +1 -1
- package/dist/libs/read_handlers.d.ts +13 -0
- package/dist/libs/read_handlers.d.ts.map +1 -0
- package/dist/libs/read_handlers.js +381 -0
- package/dist/libs/read_handlers.js.map +1 -0
- package/dist/libs/schema.js +2 -2
- package/dist/libs/schema.js.map +1 -1
- package/dist/libs/schema_serialize.d.ts +3 -0
- package/dist/libs/schema_serialize.d.ts.map +1 -0
- package/dist/libs/schema_serialize.js +45 -0
- package/dist/libs/schema_serialize.js.map +1 -0
- package/dist/libs/security.js +7 -11
- package/dist/libs/security.js.map +1 -1
- package/dist/libs/setup.js +3 -4
- package/dist/libs/setup.js.map +1 -1
- package/dist/libs/startup.d.ts +4 -0
- package/dist/libs/startup.d.ts.map +1 -1
- package/dist/libs/startup.js +17 -0
- package/dist/libs/startup.js.map +1 -1
- package/dist/models/indexquerylog_model.d.ts +19 -0
- package/dist/models/indexquerylog_model.d.ts.map +1 -0
- package/dist/models/indexquerylog_model.js +32 -0
- package/dist/models/indexquerylog_model.js.map +1 -0
- package/dist/types/jxp-config.d.ts +29 -0
- package/dist/types/jxp-config.d.ts.map +1 -1
- package/dist/types/schema-fields.d.ts +4 -0
- package/dist/types/schema-fields.d.ts.map +1 -1
- package/docs/api.md +16 -2
- package/docs/changelog.md +101 -1
- package/docs/configuration.md +39 -0
- package/docs/index.md +2 -0
- package/docs/index_diagnostics.md +127 -0
- package/docs/mcp.md +134 -0
- package/docs/schemas.md +3 -1
- package/mkdocs.yml +2 -0
- package/package.json +26 -9
- package/templates/assets/diagnostics.js +352 -0
- package/templates/assets/docs.css +107 -0
- package/templates/assets/mcp-console.js +343 -0
- package/templates/diagnostics.pug +94 -0
- package/templates/index.pug +38 -0
- package/templates/mcp.pug +112 -0
- package/templates/navbar.pug +2 -0
- package/templates/sidebar.pug +12 -0
package/dist/libs/startup.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Connection } from "mongoose";
|
|
1
2
|
export interface StartupContext {
|
|
2
3
|
name: string;
|
|
3
4
|
version: string;
|
|
@@ -8,8 +9,11 @@ export interface StartupContext {
|
|
|
8
9
|
export interface ReadyContext extends StartupContext {
|
|
9
10
|
url: string;
|
|
10
11
|
mongooseVersion: string;
|
|
12
|
+
mongoVersion?: string;
|
|
11
13
|
mongoConnectedAt: Date;
|
|
12
14
|
}
|
|
15
|
+
/** Server version from `buildInfo` (e.g. `7.0.5`). */
|
|
16
|
+
export declare function fetchMongoServerVersion(connection: Connection): Promise<string | undefined>;
|
|
13
17
|
export declare function printBanner(ctx: StartupContext): void;
|
|
14
18
|
export declare function printBooting(ctx: StartupContext): void;
|
|
15
19
|
export declare function printReady(ctx: ReadyContext): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../../src/libs/startup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../../src/libs/startup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAuB3C,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,IAAI,CAAC;CACvB;AAED,sDAAsD;AACtD,wBAAsB,uBAAuB,CAC5C,UAAU,EAAE,UAAU,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAWrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAYtD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAsBlD"}
|
package/dist/libs/startup.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchMongoServerVersion = fetchMongoServerVersion;
|
|
3
4
|
exports.printBanner = printBanner;
|
|
4
5
|
exports.printBooting = printBooting;
|
|
5
6
|
exports.printReady = printReady;
|
|
@@ -22,6 +23,19 @@ const BANNER = [
|
|
|
22
23
|
"╚█████╔╝██╔╝ ██╗██║ ",
|
|
23
24
|
" ╚════╝ ╚═╝ ╚═╝╚═╝ ",
|
|
24
25
|
].join("\n");
|
|
26
|
+
/** Server version from `buildInfo` (e.g. `7.0.5`). */
|
|
27
|
+
async function fetchMongoServerVersion(connection) {
|
|
28
|
+
try {
|
|
29
|
+
const db = connection.db;
|
|
30
|
+
if (!db)
|
|
31
|
+
return undefined;
|
|
32
|
+
const { version } = await db.admin().command({ buildInfo: 1 });
|
|
33
|
+
return typeof version === "string" ? version : undefined;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
25
39
|
function printBanner(ctx) {
|
|
26
40
|
const versionTag = `${ctx.name} v${ctx.version}`;
|
|
27
41
|
const bannerWidth = BANNER.split("\n")[0]?.length ?? versionTag.length;
|
|
@@ -54,6 +68,9 @@ function printReady(ctx) {
|
|
|
54
68
|
if (ctx.accessLog) {
|
|
55
69
|
console.log(`${c.gray} ├─${c.reset} ${c.dim}Access log${c.reset} ${ctx.accessLog}`);
|
|
56
70
|
}
|
|
71
|
+
if (ctx.mongoVersion) {
|
|
72
|
+
console.log(`${c.gray} ├─${c.reset} ${c.dim}Mongo${c.reset} v${ctx.mongoVersion}${c.reset}`);
|
|
73
|
+
}
|
|
57
74
|
console.log(`${c.gray} └─${c.reset} ${c.dim}Mongoose${c.reset} v${ctx.mongooseVersion}${c.reset}`);
|
|
58
75
|
console.log("");
|
|
59
76
|
}
|
package/dist/libs/startup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../../src/libs/startup.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../../src/libs/startup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Types } from "mongoose";
|
|
2
|
+
export interface IIndexQueryLog {
|
|
3
|
+
_id?: Types.ObjectId;
|
|
4
|
+
model_name: string;
|
|
5
|
+
op: string;
|
|
6
|
+
filter_summary: string;
|
|
7
|
+
severity: "alert" | "warn";
|
|
8
|
+
reason?: string;
|
|
9
|
+
stage?: string;
|
|
10
|
+
total_docs_examined?: number;
|
|
11
|
+
n_returned?: number;
|
|
12
|
+
total_keys_examined?: number;
|
|
13
|
+
millis?: number;
|
|
14
|
+
observed_at?: Date;
|
|
15
|
+
createdAt?: Date;
|
|
16
|
+
}
|
|
17
|
+
declare const IndexQueryLog: import("mongoose").Model<IIndexQueryLog, {}, {}, {}, any>;
|
|
18
|
+
export default IndexQueryLog;
|
|
19
|
+
//# sourceMappingURL=indexquerylog_model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexquerylog_model.d.ts","sourceRoot":"","sources":["../../src/models/indexquerylog_model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,WAAW,cAAc;IAC9B,GAAG,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,CAAC;CACjB;AAgCD,QAAA,MAAM,aAAa,2DAAwE,CAAC;AAC5F,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const schema_1 = __importDefault(require("../libs/schema"));
|
|
7
|
+
const load_config_1 = require("../libs/load-config");
|
|
8
|
+
const IndexQueryLogSchema = new schema_1.default({
|
|
9
|
+
model_name: { type: String, required: true, index: true },
|
|
10
|
+
op: { type: String, required: true },
|
|
11
|
+
filter_summary: { type: String, default: "{}" },
|
|
12
|
+
severity: { type: String, required: true, index: true },
|
|
13
|
+
reason: String,
|
|
14
|
+
stage: String,
|
|
15
|
+
total_docs_examined: Number,
|
|
16
|
+
n_returned: Number,
|
|
17
|
+
total_keys_examined: Number,
|
|
18
|
+
millis: Number,
|
|
19
|
+
observed_at: { type: Date, default: Date.now, index: true },
|
|
20
|
+
}, {
|
|
21
|
+
internal: true,
|
|
22
|
+
perms: {
|
|
23
|
+
admin: "crud",
|
|
24
|
+
owner: "",
|
|
25
|
+
user: "",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
IndexQueryLogSchema.index({ observed_at: 1 }, { expireAfterSeconds: (0, load_config_1.getIndexQueryLogRetentionSeconds)() });
|
|
29
|
+
IndexQueryLogSchema.index({ model_name: 1, severity: 1, observed_at: -1 });
|
|
30
|
+
const IndexQueryLog = schema_1.default.model("IndexQueryLog", IndexQueryLogSchema);
|
|
31
|
+
exports.default = IndexQueryLog;
|
|
32
|
+
//# sourceMappingURL=indexquerylog_model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexquerylog_model.js","sourceRoot":"","sources":["../../src/models/indexquerylog_model.ts"],"names":[],"mappings":";;;;;AAAA,4DAAuC;AACvC,qDAAuE;AAmBvE,MAAM,mBAAmB,GAAG,IAAI,gBAAS,CACxC;IACC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IACzD,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;IACpC,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;IAC/C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IACvD,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,MAAM;IACb,mBAAmB,EAAE,MAAM;IAC3B,UAAU,EAAE,MAAM;IAClB,mBAAmB,EAAE,MAAM;IAC3B,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;CAC3D,EACD;IACC,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE;QACN,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,EAAE;KACR;CACD,CACD,CAAC;AAEF,mBAAmB,CAAC,KAAK,CACxB,EAAE,WAAW,EAAE,CAAC,EAAE,EAClB,EAAE,kBAAkB,EAAE,IAAA,8CAAgC,GAAE,EAAE,CAC1D,CAAC;AACF,mBAAmB,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAE3E,MAAM,aAAa,GAAG,gBAAS,CAAC,KAAK,CAAiB,eAAe,EAAE,mBAAmB,CAAC,CAAC;AAC5F,kBAAe,aAAa,CAAC"}
|
|
@@ -13,6 +13,10 @@ export interface JXPQueryLimits {
|
|
|
13
13
|
require_limit_always?: boolean;
|
|
14
14
|
/** Skip countDocuments unless ?page= or ?count=true */
|
|
15
15
|
skip_count_unless_paginated?: boolean;
|
|
16
|
+
/** Max JSON/CSV response size (`10mb`, `512kb`, `10M`, or bytes as number); `0` disables */
|
|
17
|
+
max_response_size?: string | number;
|
|
18
|
+
/** @deprecated Use `max_response_size` (string or number) */
|
|
19
|
+
max_response_bytes?: string | number;
|
|
16
20
|
}
|
|
17
21
|
export interface JXPSecurityConfig {
|
|
18
22
|
strip_fields?: string[];
|
|
@@ -40,6 +44,29 @@ export interface JXPCacheConfig {
|
|
|
40
44
|
debug?: boolean;
|
|
41
45
|
ttl?: number;
|
|
42
46
|
}
|
|
47
|
+
export interface JXPQueryMonitorConfig {
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
/** 0–1; dev default 1.0, production default 0.02 */
|
|
50
|
+
sample_rate?: number;
|
|
51
|
+
min_docs_examined?: number;
|
|
52
|
+
docs_examined_ratio?: number;
|
|
53
|
+
small_collection_threshold?: number;
|
|
54
|
+
buffer_size?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface JXPIndexDiagnosticsConfig {
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
query_monitor?: JXPQueryMonitorConfig;
|
|
59
|
+
}
|
|
60
|
+
export interface JXPMcpConfig {
|
|
61
|
+
/** Appended after built-in MCP server instructions */
|
|
62
|
+
instructions?: string;
|
|
63
|
+
/** Markdown files merged after default.md (paths relative to cwd or absolute) */
|
|
64
|
+
guideFiles?: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface ResolvedIndexDiagnosticsConfig {
|
|
67
|
+
enabled: boolean;
|
|
68
|
+
query_monitor: Required<JXPQueryMonitorConfig>;
|
|
69
|
+
}
|
|
43
70
|
export interface JXPOAuthProviderConfig {
|
|
44
71
|
auth_uri: string;
|
|
45
72
|
token_uri: string;
|
|
@@ -75,6 +102,7 @@ export interface JXPConfig {
|
|
|
75
102
|
smtp_password?: string;
|
|
76
103
|
smtp_from?: string;
|
|
77
104
|
cache?: JXPCacheConfig;
|
|
105
|
+
index_diagnostics?: JXPIndexDiagnosticsConfig;
|
|
78
106
|
docs?: JXPDocsConfig;
|
|
79
107
|
login_rate_limit?: LoginRateLimitConfig;
|
|
80
108
|
cache_timeout?: string;
|
|
@@ -106,6 +134,7 @@ export interface JXPConfig {
|
|
|
106
134
|
post_hooks?: {
|
|
107
135
|
login?: (req: JXPRequest, res: JXPResponse) => void | Promise<void>;
|
|
108
136
|
};
|
|
137
|
+
mcp?: JXPMcpConfig;
|
|
109
138
|
}
|
|
110
139
|
/** Restify request extended by JXP middleware. */
|
|
111
140
|
export interface JXPRequest {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jxp-config.d.ts","sourceRoot":"","sources":["../../src/types/jxp-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpG,MAAM,MAAM,WAAW,GAAG,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,KACrB,IAAI,CAAC;AAEV,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uDAAuD;IACvD,2BAA2B,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"jxp-config.d.ts","sourceRoot":"","sources":["../../src/types/jxp-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,11 +25,15 @@ export interface JXPSchemaOptions {
|
|
|
25
25
|
enabled?: boolean;
|
|
26
26
|
large_collection_threshold?: number;
|
|
27
27
|
max?: number;
|
|
28
|
+
max_response_size?: string | number;
|
|
29
|
+
max_response_bytes?: string | number;
|
|
28
30
|
};
|
|
29
31
|
/** Static method names exposed via GET/POST /call/:modelname/:method_name */
|
|
30
32
|
callable_statics?: string[];
|
|
31
33
|
/** Opt out of HTTP advanced endpoints per model (default: query/aggregate on, bulkwrite off) */
|
|
32
34
|
advanced_queries?: JXPAdvancedQueries;
|
|
35
|
+
/** Framework model — hidden from docs API browser model list */
|
|
36
|
+
internal?: boolean;
|
|
33
37
|
[key: string]: unknown;
|
|
34
38
|
}
|
|
35
39
|
export type JXPDefinition = Record<string, JXPFieldDefinition | JXPFieldDefinition[] | SchemaDefinitionProperty<unknown> | SchemaDefinitionProperty<unknown>[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-fields.d.ts","sourceRoot":"","sources":["../../src/types/schema-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB,CAAC,OAAO,CAAC;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAClC,YAAY,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,GAAG,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"schema-fields.d.ts","sourceRoot":"","sources":["../../src/types/schema-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB,CAAC,OAAO,CAAC;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAClC,YAAY,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACpC,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACrC,CAAC;IACF,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CACjC,MAAM,EACJ,kBAAkB,GAClB,kBAAkB,EAAE,GACpB,wBAAwB,CAAC,OAAO,CAAC,GACjC,wBAAwB,CAAC,OAAO,CAAC,EAAE,CACrC,CAAC;AAEF,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB"}
|
package/docs/api.md
CHANGED
|
@@ -98,13 +98,26 @@ When `query_limits.enabled` is true (default), list and query endpoints apply **
|
|
|
98
98
|
|
|
99
99
|
#### Large collections (explicit limit)
|
|
100
100
|
|
|
101
|
-
For collections with at least **10,000** documents (by default), you must pass an explicit `?limit=` between 1 and the maximum. Omitting `limit` on
|
|
101
|
+
For collections with at least **10,000** documents (by default), you must pass an explicit `?limit=` between 1 and the maximum when listing **without** a filter. Omitting `limit` on an unfiltered large collection returns **400 Bad Request**.
|
|
102
|
+
|
|
103
|
+
**Filter exemption:** If the client narrows the query, the default limit applies instead:
|
|
104
|
+
|
|
105
|
+
- **GET** — non-empty `?filter[...]` (or other filter query params)
|
|
106
|
+
- **POST `/query`** — non-empty JSON `query` object in the body (not `{}`)
|
|
107
|
+
|
|
108
|
+
Filtered large-collection requests use the default limit, include pagination metadata (`count`, `page_count`, `next` when applicable), and may set **`has_more: true`** when the page is full but the total count was not computed.
|
|
109
|
+
|
|
110
|
+
**Limit cap:** If `?limit=` exceeds the configured maximum (default **1000**), the effective limit is capped to `max`. The response includes **`limit_capped: true`** and pagination links when more pages exist.
|
|
102
111
|
|
|
103
112
|
Use `GET /count/<model>` for totals. Add **`?count=true`** (or **`?page=`**) when you need `count` / `page_count` in the list response without paginating.
|
|
104
113
|
|
|
114
|
+
#### Response size limit
|
|
115
|
+
|
|
116
|
+
List, query, and CSV responses are rejected with **413 Request Entity Too Large** when the serialized payload exceeds **`max_response_size`** (default **`10mb`**). Accepts human-friendly sizes (`10mb`, `512kb`, `10M`, etc.) or a byte count as a number. Reduce `?limit=`, use `?fields=`, or paginate. Set `max_response_size: 0` or `"0"` to disable.
|
|
117
|
+
|
|
105
118
|
#### Totals in list responses
|
|
106
119
|
|
|
107
|
-
By default, list responses **omit** `count` unless you pass **`?count=true`** or **`?page=`**, to avoid expensive `countDocuments` on every request.
|
|
120
|
+
By default, list responses **omit** `count` unless you pass **`?count=true`** or **`?page=`**, to avoid expensive `countDocuments` on every request. Counts are also computed when a filtered large-collection request uses the default limit, or when the client limit was capped to `max`.
|
|
108
121
|
|
|
109
122
|
Configure globally when starting JXP:
|
|
110
123
|
|
|
@@ -115,6 +128,7 @@ query_limits: {
|
|
|
115
128
|
max: 1000,
|
|
116
129
|
default: 100,
|
|
117
130
|
skip_count_unless_paginated: true,
|
|
131
|
+
max_response_size: "10mb",
|
|
118
132
|
}
|
|
119
133
|
```
|
|
120
134
|
|
package/docs/changelog.md
CHANGED
|
@@ -2,6 +2,106 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes to [JXP](https://github.com/WorkSpaceMan/jxp).
|
|
4
4
|
|
|
5
|
+
## v5.0.0 — 2026-06-11
|
|
6
|
+
|
|
7
|
+
Read-only **MCP (Model Context Protocol)** server embedded in JXP: five fixed tools, HTTP Streamable transport, stdio bridge for Cursor/LM Studio, and LLM guidance via server instructions plus a `jxp-guide` resource.
|
|
8
|
+
|
|
9
|
+
### MCP server
|
|
10
|
+
|
|
11
|
+
#### Added
|
|
12
|
+
|
|
13
|
+
- **HTTP MCP endpoint** — `MCP_ENABLED=true` mounts `GET`/`POST` on `MCP_PATH` (default `/mcp`) on the same port as the REST API. Stateless Streamable HTTP (per-request transport).
|
|
14
|
+
- **Five fixed read-only tools** — `jxp_list_models`, `jxp_describe_model`, `jxp_find`, `jxp_count`, `jxp_export_csv`. Reuses [`read_handlers`](src/libs/read_handlers.ts); same permissions as REST `GET`.
|
|
15
|
+
- **Model visibility** — default-hide built-in auth models and `internal: true` schemas; `MCP_MODEL_WHITELIST` / `MCP_MODEL_BLACKLIST` env overrides.
|
|
16
|
+
- **MCP query limits** — stricter overlay (`MCP_DEFAULT_LIMIT`, `MCP_MAX_LIMIT`, response/CSV caps, string truncation).
|
|
17
|
+
- **LLM guidance** — server `instructions` on `initialize`; **`jxp-guide`** resource (`jxp://guide`) with built-in markdown plus app extensions via `JXPConfig.mcp` / `MCP_GUIDE_FILES`.
|
|
18
|
+
- **`jxp-mcp` CLI** — stdio bridge (`dist/bin/mcp-stdio-bridge.js`) proxies tools, resources, and instructions to a remote HTTP MCP endpoint. Env: `JXP_URL`, `JXP_API_KEY`, optional `MCP_PATH`.
|
|
19
|
+
- **Docs** — [MCP](mcp.md), `.env.sample` entries, Cursor rule `.cursor/rules/mcp.mdc`.
|
|
20
|
+
|
|
21
|
+
#### Dependencies
|
|
22
|
+
|
|
23
|
+
- `@modelcontextprotocol/server`, `@modelcontextprotocol/node`, `@modelcontextprotocol/client` (v2 alpha)
|
|
24
|
+
- `zod`, `@cfworker/json-schema` (peer for MCP client)
|
|
25
|
+
|
|
26
|
+
#### Migration
|
|
27
|
+
|
|
28
|
+
| Topic | Action |
|
|
29
|
+
|-------|--------|
|
|
30
|
+
| Opt-in | MCP is **off** by default. Set `MCP_ENABLED=true` to expose `/mcp`. |
|
|
31
|
+
| REST API | Unchanged when MCP is disabled. |
|
|
32
|
+
| New deps | `npm install` pulls MCP packages; Node **22+** (unchanged). |
|
|
33
|
+
| Cursor (HTTP) | `"url": "https://api.example.com/mcp"`, header `X-API-Key`. |
|
|
34
|
+
| Cursor (stdio) | `"command": "npx", "args": ["-y", "jxp-mcp"]`, env `JXP_URL` + `JXP_API_KEY`. |
|
|
35
|
+
|
|
36
|
+
`jxp-mcp` is **not** a separate npm package — it ships as a **bin entry on the `jxp` package** (`npx jxp-mcp` after `npm install jxp@5`). The bridge talks to a running JXP HTTP server; it does not embed the API.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## v4.2.0 — 2026-05-26
|
|
41
|
+
|
|
42
|
+
Query limit improvements, index diagnostics (audit CLI, admin API, docs UI, query monitor), built-in framework models, and MongoDB version in the startup banner.
|
|
43
|
+
|
|
44
|
+
### Index diagnostics
|
|
45
|
+
|
|
46
|
+
#### Added
|
|
47
|
+
|
|
48
|
+
- **Index audit** — Compare Mongoose schema indexes to MongoDB (`diffIndexes` / `syncIndexes`) across all loaded models. CLI: `npm run indexes` or **`jxp-indexes`** (`--json`, `--unused`, `--sync --confirm DROP_EXTRA_INDEXES`).
|
|
49
|
+
- **Admin HTTP API** — `GET /diagnostics/indexes`, `GET /diagnostics/queries`, `POST /diagnostics/indexes/sync` (admin auth).
|
|
50
|
+
- **Docs UI** — **`/docs/diagnostics`** (same sign-in as `/docs/api`): refresh audit, browse query log, sync indexes.
|
|
51
|
+
- **Query monitor** — Samples read ops (`find`, `findOne`, `count`, etc.), runs `explain('executionStats')` on a clone (async), flags **alert** / **warn** plans. Dev on by default (`QUERY_INDEX_MONITOR=true`); production via `INDEX_DIAGNOSTICS_ENABLED=true` and `QUERY_INDEX_SAMPLE_RATE`.
|
|
52
|
+
- **`IndexQueryLog` model** — Built-in MongoDB store with TTL (`INDEX_QUERY_LOG_RETENTION_DAYS`, default 30). In-memory ring buffer fallback. Log collection excluded from monitoring (no feedback loop).
|
|
53
|
+
- **`index_diagnostics` config** — `JXP({ index_diagnostics: { enabled, query_monitor: { … } } })`; call `registerQueryIndexMonitor()` before models load (sample `server.ts` does this inside `JXP()`).
|
|
54
|
+
- **Package exports** — `jxp/libs/index_diagnostics`, `jxp-indexes` bin.
|
|
55
|
+
|
|
56
|
+
See [Index diagnostics](index_diagnostics.md).
|
|
57
|
+
|
|
58
|
+
### Built-in models
|
|
59
|
+
|
|
60
|
+
#### Added
|
|
61
|
+
|
|
62
|
+
- **Package models** — When a slug is missing from `MODEL_DIR`, JXP loads from `dist/models` in the npm package: `user`, `apikey`, `token`, `refreshtoken`, `usergroups`, `indexquerylog`. App files always win.
|
|
63
|
+
- **`JXP_BUILTIN_MODELS`** — `default` (all), comma list, or `none` to disable.
|
|
64
|
+
- **`internal: true`** — Schema option to hide a model from the docs API browser model list.
|
|
65
|
+
- **`jxp/libs/builtin_models`** — `loadAllModels`, `getJxpPackageRoot`, registry helpers.
|
|
66
|
+
|
|
67
|
+
#### Changed
|
|
68
|
+
|
|
69
|
+
- **`security` / `login` / `groups` / `setup`** — Resolve auth models from the pre-loaded registry instead of `require` per file from `MODEL_DIR`.
|
|
70
|
+
- **Docs browser** — API overview lists **public** models only (built-ins with `internal: true` hidden).
|
|
71
|
+
- **Schema link preload** — Side-effect `require` only (no `.default` read) to avoid circular load issues (e.g. User → User).
|
|
72
|
+
|
|
73
|
+
### Startup
|
|
74
|
+
|
|
75
|
+
#### Added
|
|
76
|
+
|
|
77
|
+
- **MongoDB server version** — Fetched via `buildInfo` on connect and shown in the ready banner (`mongoVersion` in startup context).
|
|
78
|
+
|
|
79
|
+
### Query limits
|
|
80
|
+
|
|
81
|
+
#### Added
|
|
82
|
+
|
|
83
|
+
- **Filter exemption** — Large collections (≥ `large_collection_threshold` docs) no longer require explicit `?limit=` when the client passes a non-empty **`?filter`** (GET/CSV) or a non-empty **`query`** object (POST `/query`). The default limit applies with pagination metadata.
|
|
84
|
+
- **Response size limit** — `query_limits.max_response_size` (default **`10mb`**; env `QUERY_LIMITS_MAX_RESPONSE_SIZE`). Human-friendly sizes (`10mb`, `512kb`, `10M`) via the [`bytes`](https://www.npmjs.com/package/bytes) package. List, POST `/query`, and CSV exports return **413** when the serialized payload exceeds the limit. Numeric `max_response_bytes` remains supported for backward compatibility.
|
|
85
|
+
- **`limit_capped`** — Present when the client `?limit=` was reduced to `max`.
|
|
86
|
+
- **`has_more`** — Set when a full page was returned but total count is unknown (optimistic pagination).
|
|
87
|
+
|
|
88
|
+
#### Changed
|
|
89
|
+
|
|
90
|
+
- **`?limit=` above `max`** — Capped to `max` with pagination (was **400 Bad Request**).
|
|
91
|
+
- **`shouldRunCount`** — Also runs when filter exemption or limit cap applies, so `count` / `next` are available for protected large responses.
|
|
92
|
+
- **`query_limits.enforceListLimit`** — Returns `{ limit, limitCapped, filterExemption }`; logs **413** via `response_size` context.
|
|
93
|
+
|
|
94
|
+
#### Migration
|
|
95
|
+
|
|
96
|
+
| Scenario | v4.1.x | v4.2.0 |
|
|
97
|
+
|----------|--------|--------|
|
|
98
|
+
| Large collection, no filter, no `?limit=` | 400 | 400 (unchanged) |
|
|
99
|
+
| Large collection + `?filter` / POST body `query` | 400 | 200 with default limit + pagination |
|
|
100
|
+
| `?limit=` > max | 400 | 200 capped to `max`, `limit_capped: true` |
|
|
101
|
+
| Response > 10 MiB | (no limit) | 413 |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
5
105
|
## v4.1.1 — 2026-05-25
|
|
6
106
|
|
|
7
107
|
Bulk write authorization fixes (admins no longer need per-model opt-in) and structured request error logging for security guards (query limits, filters, aggregate, bulkwrite, auth).
|
|
@@ -37,7 +137,7 @@ Unexpected errors (non-4xx) still log a stack trace; expected `BadRequest` / `Fo
|
|
|
37
137
|
|
|
38
138
|
#### Wired into
|
|
39
139
|
|
|
40
|
-
- **`query_limits.enforceListLimit`** — missing limit on large collections
|
|
140
|
+
- **`query_limits.enforceListLimit`** — missing limit on large unfiltered collections; **`response_size`** — payload over `max_response_bytes`
|
|
41
141
|
- **Filter parsing and `query_sanitize`** — denied operators, depth, regex
|
|
42
142
|
- **POST `/query` and `/aggregate`** — model opt-in middleware, pipeline stage guard, invalid body
|
|
43
143
|
- **POST `/bulkwrite`** — opt-in, `bulkAuth`, validation, Mongo errors
|
package/docs/configuration.md
CHANGED
|
@@ -87,6 +87,18 @@ When enabled, JXP uses an in-process cache ([node-cache](https://www.npmjs.com/p
|
|
|
87
87
|
|
|
88
88
|
See [Caching](caching.md) for details.
|
|
89
89
|
|
|
90
|
+
## Index diagnostics
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
INDEX_DIAGNOSTICS_ENABLED=false
|
|
94
|
+
QUERY_INDEX_MONITOR=true
|
|
95
|
+
QUERY_INDEX_SAMPLE_RATE=1.0
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Admin endpoints (require admin login): `GET /diagnostics/indexes`, `GET /diagnostics/queries`, `POST /diagnostics/indexes/sync`. CLI: `npm run indexes` or `jxp-indexes`.
|
|
99
|
+
|
|
100
|
+
See [Index diagnostics](index_diagnostics.md).
|
|
101
|
+
|
|
90
102
|
## Query limits
|
|
91
103
|
|
|
92
104
|
```
|
|
@@ -95,6 +107,7 @@ QUERY_LIMITS_LARGE_COLLECTION_THRESHOLD=10000
|
|
|
95
107
|
QUERY_LIMITS_MAX=1000
|
|
96
108
|
QUERY_LIMITS_DEFAULT=100
|
|
97
109
|
QUERY_LIMITS_SKIP_COUNT_UNLESS_PAGINATED=true
|
|
110
|
+
QUERY_LIMITS_MAX_RESPONSE_SIZE=10mb
|
|
98
111
|
CORS_ORIGINS=http://localhost:3000,http://localhost:4001
|
|
99
112
|
```
|
|
100
113
|
|
|
@@ -112,6 +125,32 @@ JXP discovers models by scanning `MODEL_DIR` for `*_model.js`. You can also pass
|
|
|
112
125
|
|
|
113
126
|
Relative `model_dir` paths resolve from `process.cwd()` (typical for npm scripts), not from the server script path.
|
|
114
127
|
|
|
128
|
+
### Built-in models
|
|
129
|
+
|
|
130
|
+
JXP ships framework models in the npm package (`dist/models`). If a slug is **missing** from your `MODEL_DIR`, JXP loads the built-in automatically (your app always wins when you provide the same `{slug}_model.js`):
|
|
131
|
+
|
|
132
|
+
| Slug | Purpose |
|
|
133
|
+
|------|---------|
|
|
134
|
+
| `user` | Users / login |
|
|
135
|
+
| `apikey` | API keys |
|
|
136
|
+
| `token` | Access tokens |
|
|
137
|
+
| `refreshtoken` | Refresh tokens |
|
|
138
|
+
| `usergroups` | Group membership |
|
|
139
|
+
| `indexquerylog` | Index diagnostics query log ([Index diagnostics](index_diagnostics.md)) |
|
|
140
|
+
|
|
141
|
+
Optional:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
# default — load all built-ins when missing
|
|
145
|
+
# JXP_BUILTIN_MODELS=default
|
|
146
|
+
|
|
147
|
+
# comma list, or none to disable
|
|
148
|
+
# JXP_BUILTIN_MODELS=user,apikey,token
|
|
149
|
+
# JXP_BUILTIN_MODELS=none
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Schemas can set `internal: true` in schema options to hide a model from the docs API browser list (see [Schemas](schemas.md)).
|
|
153
|
+
|
|
115
154
|
## Programmatic config
|
|
116
155
|
|
|
117
156
|
Apps typically build an options object and pass it to `JXP()`:
|
package/docs/index.md
CHANGED
|
@@ -17,6 +17,8 @@ JXP 4 requires **Node.js 22+**, ships as compiled TypeScript, and uses environme
|
|
|
17
17
|
* Hooks for business logic
|
|
18
18
|
* Stateless and easy to deploy
|
|
19
19
|
* WebSocket change subscriptions
|
|
20
|
+
* [Index diagnostics](index_diagnostics.md) — schema vs DB indexes and optional query monitoring
|
|
21
|
+
* [MCP](mcp.md) — read-only Model Context Protocol for AI clients (Cursor, LM Studio); optional `jxp-mcp` stdio bridge
|
|
20
22
|
|
|
21
23
|
## Links
|
|
22
24
|
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Index diagnostics and query monitoring
|
|
2
|
+
|
|
3
|
+
JXP can compare **Mongoose schema indexes** to indexes in MongoDB, optionally sync them, and (when enabled) sample read queries with `explain('executionStats')` to flag likely unindexed or inefficient access patterns.
|
|
4
|
+
|
|
5
|
+
## Index audit (schema vs database)
|
|
6
|
+
|
|
7
|
+
Mongoose provides `Model.diffIndexes()` and `Model.syncIndexes()`. JXP wraps these for all loaded models.
|
|
8
|
+
|
|
9
|
+
### CLI
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run indexes
|
|
13
|
+
# or
|
|
14
|
+
npx jxp-indexes
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Flag | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `--json` | Machine-readable report |
|
|
20
|
+
| `--unused` | Include `$indexStats` hints for indexes with zero ops |
|
|
21
|
+
| `--sync` | Apply `syncIndexes()` (create missing, drop extras) |
|
|
22
|
+
| `--confirm DROP_EXTRA_INDEXES` | Required with `--sync` |
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm run indexes -- --json
|
|
28
|
+
npm run indexes -- --sync --confirm DROP_EXTRA_INDEXES
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Exit code `1` when any collection has missing or extra indexes (audit mode only).
|
|
32
|
+
|
|
33
|
+
Requires `MODEL_DIR` and Mongo connection env vars (same as the API server).
|
|
34
|
+
|
|
35
|
+
### Web UI
|
|
36
|
+
|
|
37
|
+
Open **`/docs/diagnostics`** in the API docs browser (same sign-in as `/docs/api`). The page lets admins:
|
|
38
|
+
|
|
39
|
+
- Refresh the index audit and view missing/extra indexes per collection
|
|
40
|
+
- Browse the query log (from MongoDB when the `IndexQueryLog` model is loaded)
|
|
41
|
+
- Sync indexes after typing `DROP_EXTRA_INDEXES`
|
|
42
|
+
|
|
43
|
+
Use an **admin** API key in the docs top bar.
|
|
44
|
+
|
|
45
|
+
### Admin HTTP API
|
|
46
|
+
|
|
47
|
+
Admin authentication required (`security.admin_only`).
|
|
48
|
+
|
|
49
|
+
| Method | Path | Description |
|
|
50
|
+
|--------|------|-------------|
|
|
51
|
+
| GET | `/diagnostics/indexes` | Audit report (`?refresh=true`, `?unused=true`) |
|
|
52
|
+
| GET | `/diagnostics/queries` | Recent query monitor entries + config |
|
|
53
|
+
| POST | `/diagnostics/indexes/sync` | Body `{ "confirm": "DROP_EXTRA_INDEXES" }` |
|
|
54
|
+
|
|
55
|
+
## Query monitor
|
|
56
|
+
|
|
57
|
+
MongoDB does not emit “missing index” events. When the monitor is enabled, JXP samples read operations (`find`, `findOne`, `count`, `countDocuments`, `distinct`), runs `explain('executionStats')` on a **clone** of the query (async, non-blocking), and records **alert** / **warn** entries.
|
|
58
|
+
|
|
59
|
+
### Where queries are stored
|
|
60
|
+
|
|
61
|
+
| Layer | Purpose |
|
|
62
|
+
|-------|---------|
|
|
63
|
+
| **`IndexQueryLog` model** (MongoDB) | Primary store — one document per flagged query. Auto-loaded from the jxp package (`indexquerylog_model.js`). TTL via `INDEX_QUERY_LOG_RETENTION_DAYS` (default 30). |
|
|
64
|
+
| **In-memory ring buffer** | Fast fallback when the model is unavailable; also used for recent samples before persistence. Size: `QUERY_INDEX_BUFFER_SIZE`. |
|
|
65
|
+
|
|
66
|
+
The `IndexQueryLog` collection is excluded from query monitoring (reads/writes to the log do not create new log entries). Explain runs use `query.clone().explain()` with an internal flag so Mongoose post hooks do not treat the explain as another sampled query (no monitor loop). The model is a **built-in** — you do not need `indexquerylog_model.js` in your app's `MODEL_DIR` unless you want to override it (see [Configuration — Built-in models](configuration.md#built-in-models)). Admins can also list logs via `GET /api/indexquerylog` with normal JXP filters.
|
|
67
|
+
|
|
68
|
+
Query monitor is enabled in development by default (`QUERY_INDEX_MONITOR=true`). In production, set `INDEX_DIAGNOSTICS_ENABLED=true` and tune `QUERY_INDEX_SAMPLE_RATE` (e.g. `0.02`).
|
|
69
|
+
|
|
70
|
+
**Heuristics (approximate):**
|
|
71
|
+
|
|
72
|
+
- **alert** — `COLLSCAN` (or nested collection scan) with high `totalDocsExamined` vs `nReturned`
|
|
73
|
+
- **warn** — index used but many more documents examined than returned
|
|
74
|
+
- **ignore** — small collections (below threshold), or benign plans
|
|
75
|
+
|
|
76
|
+
`explain` with `executionStats` executes the query again — use sampling in production.
|
|
77
|
+
|
|
78
|
+
### Environment variables
|
|
79
|
+
|
|
80
|
+
| Variable | Default (dev) | Default (production) |
|
|
81
|
+
|----------|---------------|----------------------|
|
|
82
|
+
| `INDEX_DIAGNOSTICS_ENABLED` | off | off (master enable for prod) |
|
|
83
|
+
| `QUERY_INDEX_MONITOR` | `true` | `false` |
|
|
84
|
+
| `QUERY_INDEX_SAMPLE_RATE` | `1.0` | `0.02` |
|
|
85
|
+
| `QUERY_INDEX_MIN_DOCS_EXAMINED` | `20` | `100` |
|
|
86
|
+
| `QUERY_INDEX_DOCS_EXAMINED_RATIO` | `5` | `10` |
|
|
87
|
+
| `QUERY_INDEX_SMALL_COLLECTION_THRESHOLD` | `500` | `1000` |
|
|
88
|
+
| `QUERY_INDEX_BUFFER_SIZE` | `200` | `200` |
|
|
89
|
+
| `INDEX_QUERY_LOG_RETENTION_DAYS` | `30` | `30` |
|
|
90
|
+
|
|
91
|
+
In production, set `INDEX_DIAGNOSTICS_ENABLED=true` (and tune sample rate) to enable monitoring.
|
|
92
|
+
|
|
93
|
+
### Config object
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
JXP({
|
|
97
|
+
index_diagnostics: {
|
|
98
|
+
enabled: true,
|
|
99
|
+
query_monitor: {
|
|
100
|
+
enabled: true,
|
|
101
|
+
sample_rate: 0.05,
|
|
102
|
+
min_docs_examined: 100,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Register the monitor **before** models load (the sample `server.ts` calls `registerQueryIndexMonitor()` before `JXP()`).
|
|
109
|
+
|
|
110
|
+
## Programmatic use
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
const {
|
|
114
|
+
auditAllModels,
|
|
115
|
+
syncAllModels,
|
|
116
|
+
loadModelsFromDir,
|
|
117
|
+
classifyExplain,
|
|
118
|
+
} = require("jxp/libs/index_diagnostics");
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Complementary tools
|
|
122
|
+
|
|
123
|
+
- MongoDB [Profiler](https://www.mongodb.com/docs/manual/tutorial/manage-the-database-profiler/) and Compass — slow query analysis
|
|
124
|
+
- Atlas Performance Advisor — index suggestions (Atlas)
|
|
125
|
+
- `db.collection.explain()` — manual plan inspection
|
|
126
|
+
|
|
127
|
+
JXP diagnostics do not replace these; they integrate index drift checks into your JXP app workflow.
|