mongodb-models-visualizer 0.1.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/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # mongodb-visualizer
2
+
3
+ 🚀 **Swagger-like Analyzer for MongoDB (Mongoose) Models**
4
+
5
+ Automatically analyze, visualize, and document your MongoDB models in a Node.js + Express application.
6
+
7
+ ---
8
+
9
+ ## ✨ What is mongodb-visualizer?
10
+
11
+ `mongodb-visualizer` is a developer tool that introspects your **Mongoose models** and provides:
12
+
13
+ - List of all registered models
14
+ - Schema fields with types & validations
15
+ - Model relationships (`ref`)
16
+ - Collection names
17
+ - Optional sample documents
18
+ - Swagger-like web UI
19
+ - JSON APIs for documentation & automation
20
+
21
+ Think of it as **Swagger, but for MongoDB schemas**.
22
+
23
+ ---
24
+
25
+ ## 🔧 Supported Stack
26
+
27
+ - Node.js ≥ 16
28
+ - Express ≥ 4
29
+ - Mongoose ≥ 6
30
+
31
+ ---
32
+
33
+ ## 📦 Installation
34
+
35
+ ```bash
36
+ npm install mongodb-visualizer
37
+ ```
38
+
39
+ or
40
+
41
+ ```bash
42
+ yarn add mongodb-visualizer
43
+ ```
44
+
45
+ ## 🚀 Quick Start
46
+
47
+ ### 1️⃣ Setup Express & Mongoose
48
+
49
+ ```javascript
50
+ import express from 'express'
51
+ import mongoose from 'mongoose'
52
+ import { modelAnalyzer } from 'mongodb-visualizer'
53
+
54
+ const app = express()
55
+
56
+ mongoose.connect(process.env.MONGO_URI)
57
+ ```
58
+
59
+ ### 2️⃣ Mount the Analyzer Middleware
60
+
61
+ ```javascript
62
+ app.use(
63
+ '/models-analyzer',
64
+ modelAnalyzer({
65
+ mongoose
66
+ })
67
+ )
68
+ ```
69
+
70
+ ### 3️⃣ Start the Server
71
+
72
+ ```javascript
73
+ app.listen(3000, () => {
74
+ console.log('Server running on http://localhost:3000')
75
+ })
76
+ ```
77
+
78
+ ### 4️⃣ Open in Browser 🎉
79
+
80
+ Navigate to `http://localhost:3000/models-analyzer`
81
+
82
+ ## 📊 API Endpoints
83
+
84
+ ### 🔹 Get all models
85
+
86
+ ```
87
+ GET /models-analyzer/api/models
88
+ ```
89
+
90
+ **Example Response:**
91
+
92
+ ```json
93
+ [
94
+ {
95
+ "name": "User",
96
+ "collection": "users",
97
+ "fields": [
98
+ {
99
+ "name": "email",
100
+ "instance": "String",
101
+ "required": true,
102
+ "enum": [],
103
+ "ref": null
104
+ }
105
+ ]
106
+ }
107
+ ]
108
+ ```
109
+
110
+ ### 🔹 Get a single model
111
+
112
+ ```
113
+ GET /models-analyzer/api/models/:modelName
114
+ ```
115
+
116
+ ## ⚙️ Configuration Options
117
+
118
+ ```javascript
119
+ modelAnalyzer({
120
+ mongoose, // required
121
+ sampleDocs: true, // optional (default: false)
122
+ auth: false // optional (default: false)
123
+ })
124
+ ```
125
+
126
+ | Option | Type | Description |
127
+ |--------|------|-------------|
128
+ | mongoose | Object | Mongoose instance |
129
+ | sampleDocs | Boolean | Include sample documents |
130
+ | auth | Boolean | Enable auth middleware |
131
+
132
+ ## ## 🔐 Security (Recommended for Production)
133
+
134
+ Do NOT expose this endpoint publicly without authentication.
135
+
136
+ **Example using basic auth:**
137
+
138
+ ```javascript
139
+ import basicAuth from 'express-basic-auth'
140
+
141
+ app.use(
142
+ '/models-analyzer',
143
+ basicAuth({
144
+ users: { admin: 'password' },
145
+ challenge: true
146
+ }),
147
+ modelAnalyzer({ mongoose })
148
+ )
149
+ ```
150
+
151
+ ## 🧠 How It Works
152
+
153
+ 1. Scans all registered Mongoose models
154
+ 2. Extracts schema metadata
155
+ 3. Parses fields, types, refs, and indexes
156
+ 4. Builds structured JSON output
157
+ 5. Serves data via API & UI
158
+
159
+ ## 🗺️ Roadmap
160
+
161
+ ### ✅ v0.1 (Current)
162
+
163
+ - Model scanner
164
+ - Schema parser
165
+ - JSON APIs
166
+
167
+ ### 🚀 v0.2
168
+
169
+ - Swagger-like UI
170
+ - Relationship graph
171
+ - Index analyzer
172
+
173
+ ### 🧠 v1.0
174
+
175
+ - Performance suggestions
176
+ - Migration hints
177
+ - CLI support
178
+ - Fastify & NestJS adapters
179
+
180
+ ## 🤝 Contributing
181
+
182
+ Contributions are welcome!
183
+
184
+ ```bash
185
+ git clone https://github.com/Hibbanur-Rahman/mongodb-visualizer.git
186
+ cd mongodb-visualizer
187
+ npm install
188
+ npm run build
189
+ ```
190
+
191
+ Feel free to open issues or pull requests 🚀
192
+
193
+ ## 📄 License
194
+
195
+ MIT License © 2026
196
+
197
+ ## ❤️ Why This Tool?
198
+
199
+ - MongoDB has no built-in schema visualization
200
+ - Helps onboarding new developers
201
+ - Great for documentation & debugging
202
+ - Inspired by Swagger & Prisma Studio
203
+
204
+ ---
205
+
206
+ **Next steps you can take:**
207
+ - Add npm badges
208
+ - Write a CONTRIBUTING.md
209
+ - Create a docs website
210
+ - Prepare a demo GIF
211
+
212
+ Let me know what's next! 🚀
package/dist/index.cjs ADDED
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ modelAnalyzer: () => modelAnalyzer
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/express/middleware.ts
38
+ var import_express = __toESM(require("express"), 1);
39
+
40
+ // src/core/scanModels.ts
41
+ var import_mongoose = require("mongoose");
42
+ function scanModels(mongoose) {
43
+ return mongoose.modelNames().map((name) => {
44
+ const model = mongoose.model(name);
45
+ return {
46
+ name,
47
+ collection: model.collection.name,
48
+ schema: model.schema
49
+ };
50
+ });
51
+ }
52
+
53
+ // src/core/parseSchema.ts
54
+ var import_mongoose2 = require("mongoose");
55
+ function parseSchema(schema) {
56
+ const fields = [];
57
+ schema.eachPath((path, type) => {
58
+ fields.push({
59
+ name: path,
60
+ instance: type.instance,
61
+ required: !!type.isRequired,
62
+ enum: type.enumValues || [],
63
+ ref: type.options?.ref
64
+ });
65
+ });
66
+ return fields;
67
+ }
68
+
69
+ // src/express/middleware.ts
70
+ function modelAnalyzer(options) {
71
+ const router = import_express.default.Router();
72
+ router.get("/api/models", (req, res) => {
73
+ const models = scanModels(options.mongoose).map((m) => ({
74
+ name: m.name,
75
+ collection: m.collection,
76
+ fields: parseSchema(m.schema)
77
+ }));
78
+ res.json(models);
79
+ });
80
+ return router;
81
+ }
82
+ // Annotate the CommonJS export names for ESM import in node:
83
+ 0 && (module.exports = {
84
+ modelAnalyzer
85
+ });
@@ -0,0 +1,7 @@
1
+ import * as express_serve_static_core from 'express-serve-static-core';
2
+
3
+ declare function modelAnalyzer(options: {
4
+ mongoose: any;
5
+ }): express_serve_static_core.Router;
6
+
7
+ export { modelAnalyzer };
@@ -0,0 +1,7 @@
1
+ import * as express_serve_static_core from 'express-serve-static-core';
2
+
3
+ declare function modelAnalyzer(options: {
4
+ mongoose: any;
5
+ }): express_serve_static_core.Router;
6
+
7
+ export { modelAnalyzer };
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ // src/express/middleware.ts
2
+ import express from "express";
3
+
4
+ // src/core/scanModels.ts
5
+ import "mongoose";
6
+ function scanModels(mongoose) {
7
+ return mongoose.modelNames().map((name) => {
8
+ const model = mongoose.model(name);
9
+ return {
10
+ name,
11
+ collection: model.collection.name,
12
+ schema: model.schema
13
+ };
14
+ });
15
+ }
16
+
17
+ // src/core/parseSchema.ts
18
+ import "mongoose";
19
+ function parseSchema(schema) {
20
+ const fields = [];
21
+ schema.eachPath((path, type) => {
22
+ fields.push({
23
+ name: path,
24
+ instance: type.instance,
25
+ required: !!type.isRequired,
26
+ enum: type.enumValues || [],
27
+ ref: type.options?.ref
28
+ });
29
+ });
30
+ return fields;
31
+ }
32
+
33
+ // src/express/middleware.ts
34
+ function modelAnalyzer(options) {
35
+ const router = express.Router();
36
+ router.get("/api/models", (req, res) => {
37
+ const models = scanModels(options.mongoose).map((m) => ({
38
+ name: m.name,
39
+ collection: m.collection,
40
+ fields: parseSchema(m.schema)
41
+ }));
42
+ res.json(models);
43
+ });
44
+ return router;
45
+ }
46
+ export {
47
+ modelAnalyzer
48
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "mongodb-models-visualizer",
3
+ "version": "0.1.0",
4
+ "description": "MongoDB Database Visualizer and models relationships between collections",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ }
13
+ },
14
+ "peerDependencies": {
15
+ "mongoose": ">=6",
16
+ "express": ">=4"
17
+ },
18
+ "scripts": {
19
+ "test": "echo \"Error: no test specified\" && exit 1",
20
+ "build": "tsup",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/Hibbanur-Rahman/mongodb-visualizer.git"
26
+ },
27
+ "keywords": [],
28
+ "author": "Hibbanur Rahman",
29
+ "license": "ISC",
30
+ "type": "module",
31
+ "bugs": {
32
+ "url": "https://github.com/Hibbanur-Rahman/mongodb-visualizer/issues"
33
+ },
34
+ "homepage": "https://github.com/Hibbanur-Rahman/mongodb-visualizer#readme",
35
+ "devDependencies": {
36
+ "@types/express": "^5.0.6",
37
+ "@types/node": "^25.2.2",
38
+ "tsup": "^8.5.1",
39
+ "typescript": "^5.9.3"
40
+ },
41
+ "dependencies": {
42
+ "express": "^5.2.1",
43
+ "mongoose": "^9.1.6"
44
+ }
45
+ }
File without changes
@@ -0,0 +1,17 @@
1
+ import { Schema } from 'mongoose'
2
+
3
+ export function parseSchema(schema: Schema) {
4
+ const fields: any[] = []
5
+
6
+ schema.eachPath((path, type: any) => {
7
+ fields.push({
8
+ name: path,
9
+ instance: type.instance,
10
+ required: !!type.isRequired,
11
+ enum: type.enumValues || [],
12
+ ref: type.options?.ref
13
+ })
14
+ })
15
+
16
+ return fields
17
+ }
@@ -0,0 +1,12 @@
1
+ import { Mongoose } from 'mongoose'
2
+
3
+ export function scanModels(mongoose: Mongoose) {
4
+ return mongoose.modelNames().map((name) => {
5
+ const model = mongoose.model(name)
6
+ return {
7
+ name,
8
+ collection: model.collection.name,
9
+ schema: model.schema
10
+ }
11
+ })
12
+ }
@@ -0,0 +1 @@
1
+ export { modelAnalyzer } from './middleware'
@@ -0,0 +1,21 @@
1
+ import express from 'express'
2
+ import { scanModels } from '../core/scanModels'
3
+ import { parseSchema } from '../core/parseSchema'
4
+
5
+ export function modelAnalyzer(options: {
6
+ mongoose: any
7
+ }) {
8
+ const router = express.Router()
9
+
10
+ router.get('/api/models', (req, res) => {
11
+ const models = scanModels(options.mongoose).map((m) => ({
12
+ name: m.name,
13
+ collection: m.collection,
14
+ fields: parseSchema(m.schema)
15
+ }))
16
+
17
+ res.json(models)
18
+ })
19
+
20
+ return router
21
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { modelAnalyzer } from './express'
File without changes
package/tsconfig.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ // "rootDir": "./src",
6
+ "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "ESNext",
11
+ "moduleResolution": "bundler",
12
+ "target": "ES2020",
13
+ "types": [],
14
+ // For nodejs:
15
+ // "lib": ["esnext"],
16
+ // "types": ["node"],
17
+ // and npm install -D @types/node
18
+
19
+ // Other Outputs
20
+ "sourceMap": true,
21
+ "declaration": true,
22
+ "declarationMap": true,
23
+
24
+ // Stricter Typechecking Options
25
+ "noUncheckedIndexedAccess": true,
26
+ "exactOptionalPropertyTypes": true,
27
+
28
+ // Style Options
29
+ // "noImplicitReturns": true,
30
+ // "noImplicitOverride": true,
31
+ // "noUnusedLocals": true,
32
+ // "noUnusedParameters": true,
33
+ // "noFallthroughCasesInSwitch": true,
34
+ // "noPropertyAccessFromIndexSignature": true,
35
+
36
+ // Recommended Options
37
+ "strict": true,
38
+ "jsx": "react-jsx",
39
+ "verbatimModuleSyntax": true,
40
+ "isolatedModules": true,
41
+ "noUncheckedSideEffectImports": true,
42
+ "moduleDetection": "force",
43
+ "skipLibCheck": true,
44
+ }
45
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['cjs', 'esm'],
6
+ dts: true,
7
+ clean: true
8
+ })