db-model-router 1.0.3 → 1.0.5

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.
Files changed (97) hide show
  1. package/README.md +283 -25
  2. package/TODO.md +14 -0
  3. package/dbmr.schema.json +333 -0
  4. package/demo/.dockerignore +7 -0
  5. package/demo/.env.example +13 -0
  6. package/demo/Dockerfile +20 -0
  7. package/demo/app.js +37 -0
  8. package/demo/commons/add_migration.js +43 -0
  9. package/demo/commons/db.js +17 -0
  10. package/demo/commons/migrate.js +65 -0
  11. package/demo/commons/security.js +30 -0
  12. package/demo/commons/session.js +13 -0
  13. package/demo/dbmr.schema.json +362 -0
  14. package/demo/docs/llm.md +197 -0
  15. package/demo/llms.txt +70 -0
  16. package/demo/middleware/logger.js +67 -0
  17. package/demo/migrations/20260430155808_create_migrations_table.sql +6 -0
  18. package/demo/migrations/20260430155809_create_tables.sql +207 -0
  19. package/demo/models/addresses.js +22 -0
  20. package/demo/models/cart_items.js +18 -0
  21. package/demo/models/carts.js +16 -0
  22. package/demo/models/categories.js +20 -0
  23. package/demo/models/coupons.js +23 -0
  24. package/demo/models/order_items.js +21 -0
  25. package/demo/models/orders.js +25 -0
  26. package/demo/models/payments.js +21 -0
  27. package/demo/models/product_images.js +18 -0
  28. package/demo/models/product_reviews.js +20 -0
  29. package/demo/models/product_variants.js +20 -0
  30. package/demo/models/products.js +30 -0
  31. package/demo/models/shipments.js +19 -0
  32. package/demo/models/users.js +19 -0
  33. package/demo/models/wishlists.js +15 -0
  34. package/demo/openapi.json +5872 -0
  35. package/demo/package-lock.json +2810 -0
  36. package/demo/package.json +34 -0
  37. package/demo/routes/addresses.js +6 -0
  38. package/demo/routes/carts/cart_items.js +7 -0
  39. package/demo/routes/carts.js +6 -0
  40. package/demo/routes/categories.js +6 -0
  41. package/demo/routes/coupons.js +6 -0
  42. package/demo/routes/docs.js +18 -0
  43. package/demo/routes/health.js +35 -0
  44. package/demo/routes/index.js +39 -0
  45. package/demo/routes/orders/order_items.js +7 -0
  46. package/demo/routes/orders/payments.js +7 -0
  47. package/demo/routes/orders/shipments.js +7 -0
  48. package/demo/routes/orders.js +6 -0
  49. package/demo/routes/products/product_images.js +7 -0
  50. package/demo/routes/products/product_reviews.js +7 -0
  51. package/demo/routes/products/product_variants.js +7 -0
  52. package/demo/routes/products.js +6 -0
  53. package/demo/routes/users.js +6 -0
  54. package/demo/routes/wishlists.js +6 -0
  55. package/docker-compose.yml +1 -1
  56. package/package.json +16 -7
  57. package/scripts/demo-create.js +47 -0
  58. package/skill/SKILL.md +464 -0
  59. package/skill/references/cockroachdb.md +49 -0
  60. package/skill/references/dynamodb.md +53 -0
  61. package/skill/references/mongodb.md +56 -0
  62. package/skill/references/mssql.md +55 -0
  63. package/skill/references/oracle.md +52 -0
  64. package/skill/references/postgres.md +50 -0
  65. package/skill/references/redis.md +53 -0
  66. package/skill/references/sqlite3.md +43 -0
  67. package/src/cli/commands/generate.js +58 -17
  68. package/src/cli/commands/help.js +185 -0
  69. package/src/cli/commands/init.js +42 -14
  70. package/src/cli/commands/inspect.js +21 -3
  71. package/src/cli/diff-engine.js +52 -22
  72. package/src/cli/generate-docs-route.js +31 -0
  73. package/src/cli/generate-migration.js +356 -0
  74. package/src/cli/generate-model.js +5 -4
  75. package/src/cli/generate-route.js +79 -45
  76. package/src/cli/init/dependencies.js +17 -5
  77. package/src/cli/init/generators.js +1073 -64
  78. package/src/cli/init/prompt.js +37 -5
  79. package/src/cli/init.js +148 -25
  80. package/src/cli/main.js +90 -10
  81. package/src/cockroachdb/db.js +90 -59
  82. package/src/commons/route.js +20 -20
  83. package/src/commons/validator.js +58 -1
  84. package/src/dynamodb/db.js +50 -27
  85. package/src/index.js +2 -0
  86. package/src/mongodb/db.js +1 -0
  87. package/src/mssql/db.js +89 -61
  88. package/src/mysql/db.js +1 -0
  89. package/src/oracle/db.js +1 -0
  90. package/src/postgres/db.js +61 -41
  91. package/src/redis/db.js +1 -0
  92. package/src/schema/schema-parser.js +43 -1
  93. package/src/schema/schema-printer.js +8 -5
  94. package/src/schema/schema-to-meta.js +4 -0
  95. package/src/schema/schema-validator.js +20 -1
  96. package/src/sqlite3/db.js +1 -0
  97. package/docs/SKILL.md +0 -374
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "demo",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "start": "node app.js",
9
+ "dev": "nodemon app.js",
10
+ "migrate": "node commons/migrate.js",
11
+ "add_migration": "node commons/add_migration.js",
12
+ "docker:build": "docker build -t app .",
13
+ "docker:up": "docker compose up -d",
14
+ "docker:down": "docker compose down"
15
+ },
16
+ "keywords": [],
17
+ "author": "",
18
+ "license": "ISC",
19
+ "type": "module",
20
+ "dependencies": {
21
+ "db-model-router": "latest",
22
+ "dotenv": "latest",
23
+ "express": "latest",
24
+ "express-session": "latest",
25
+ "better-sqlite3": "latest",
26
+ "express-rate-limit": "latest",
27
+ "helmet": "latest",
28
+ "winston": "latest",
29
+ "swagger-ui-express": "latest"
30
+ },
31
+ "devDependencies": {
32
+ "nodemon": "latest"
33
+ }
34
+ }
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import addresses from "../models/addresses.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(addresses);
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import cart_items from "../../models/cart_items.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent carts via cart_id
7
+ export default route(cart_items, { cart_id: "params.cart_id" });
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import carts from "../models/carts.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(carts);
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import categories from "../models/categories.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(categories);
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import coupons from "../models/coupons.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(coupons);
@@ -0,0 +1,18 @@
1
+ import express from "express";
2
+ import swaggerUi from "swagger-ui-express";
3
+ import { readFileSync } from "fs";
4
+ import { dirname, join } from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const spec = JSON.parse(readFileSync(join(__dirname, "../openapi.json"), "utf8"));
9
+
10
+ const router = express.Router();
11
+
12
+ router.use("/", swaggerUi.serve);
13
+ router.get("/", swaggerUi.setup(spec, {
14
+ customSiteTitle: "API Documentation",
15
+ customCss: ".swagger-ui .topbar { display: none }",
16
+ }));
17
+
18
+ export default router;
@@ -0,0 +1,35 @@
1
+ import express from "express";
2
+
3
+ const router = express.Router();
4
+
5
+ /**
6
+ * GET /health
7
+ * Returns server health status, uptime, memory, and database connectivity.
8
+ */
9
+ router.get("/", async (req, res) => {
10
+ const health = {
11
+ status: "ok",
12
+ timestamp: new Date().toISOString(),
13
+ uptime: process.uptime(),
14
+ memory: process.memoryUsage(),
15
+ db: { connected: false },
16
+ };
17
+
18
+ try {
19
+ if (global.db && typeof global.db.query === "function") {
20
+ await global.db.query("SELECT NOW()");
21
+ health.db.connected = true;
22
+ } else if (global.db && typeof global.db.get === "function") {
23
+ // NoSQL adapters (mongodb, redis, dynamodb)
24
+ health.db.connected = true;
25
+ }
26
+ } catch (err) {
27
+ health.status = "degraded";
28
+ health.db.error = err.message;
29
+ }
30
+
31
+ const statusCode = health.status === "ok" ? 200 : 503;
32
+ res.status(statusCode).json(health);
33
+ });
34
+
35
+ export default router;
@@ -0,0 +1,39 @@
1
+ import express from "express";
2
+
3
+ const router = express.Router();
4
+
5
+ import addressesRoute from "./addresses.js";
6
+ import cartsRoute from "./carts.js";
7
+ import categoriesRoute from "./categories.js";
8
+ import couponsRoute from "./coupons.js";
9
+ import ordersRoute from "./orders.js";
10
+ import productsRoute from "./products.js";
11
+ import usersRoute from "./users.js";
12
+ import wishlistsRoute from "./wishlists.js";
13
+ import product_imagesChildRoute from "./products/product_images.js";
14
+ import product_variantsChildRoute from "./products/product_variants.js";
15
+ import product_reviewsChildRoute from "./products/product_reviews.js";
16
+ import cart_itemsChildRoute from "./carts/cart_items.js";
17
+ import order_itemsChildRoute from "./orders/order_items.js";
18
+ import paymentsChildRoute from "./orders/payments.js";
19
+ import shipmentsChildRoute from "./orders/shipments.js";
20
+ import docsRoute from "./docs.js";
21
+
22
+ router.use("/docs", docsRoute);
23
+ router.use("/addresses", addressesRoute);
24
+ router.use("/carts", cartsRoute);
25
+ router.use("/categories", categoriesRoute);
26
+ router.use("/coupons", couponsRoute);
27
+ router.use("/orders", ordersRoute);
28
+ router.use("/products", productsRoute);
29
+ router.use("/users", usersRoute);
30
+ router.use("/wishlists", wishlistsRoute);
31
+ router.use("/products/:product_id/product_images", product_imagesChildRoute);
32
+ router.use("/products/:product_id/product_variants", product_variantsChildRoute);
33
+ router.use("/products/:product_id/product_reviews", product_reviewsChildRoute);
34
+ router.use("/carts/:cart_id/cart_items", cart_itemsChildRoute);
35
+ router.use("/orders/:order_id/order_items", order_itemsChildRoute);
36
+ router.use("/orders/:order_id/payments", paymentsChildRoute);
37
+ router.use("/orders/:order_id/shipments", shipmentsChildRoute);
38
+
39
+ export default router;
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import order_items from "../../models/order_items.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent orders via order_id
7
+ export default route(order_items, { order_id: "params.order_id" });
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import payments from "../../models/payments.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent orders via order_id
7
+ export default route(payments, { order_id: "params.order_id" });
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import shipments from "../../models/shipments.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent orders via order_id
7
+ export default route(shipments, { order_id: "params.order_id" });
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import orders from "../models/orders.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(orders);
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import product_images from "../../models/product_images.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent products via product_id
7
+ export default route(product_images, { product_id: "params.product_id" });
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import product_reviews from "../../models/product_reviews.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent products via product_id
7
+ export default route(product_reviews, { product_id: "params.product_id" });
@@ -0,0 +1,7 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import product_variants from "../../models/product_variants.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ // Child route: scoped by parent products via product_id
7
+ export default route(product_variants, { product_id: "params.product_id" });
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import products from "../models/products.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(products);
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import users from "../models/users.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(users);
@@ -0,0 +1,6 @@
1
+ import dbModelRouter from "db-model-router";
2
+ import wishlists from "../models/wishlists.js";
3
+
4
+ const { route } = dbModelRouter;
5
+
6
+ export default route(wishlists);
@@ -128,7 +128,7 @@ services:
128
128
  - db-network
129
129
 
130
130
  oracle:
131
- image: gvenzl/oracle-xe:21-slim
131
+ image: gvenzl/oracle-free
132
132
  container_name: db-model-router-oracle
133
133
  restart: unless-stopped
134
134
  ports:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "db-model-router",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Generative API Creation using mysql2 and express libraries in node js",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -19,7 +19,9 @@
19
19
  "test:cockroachdb": "dotenv -e env/.env.cockroachdb -- mocha test/adapters/cockroachdb.*.test.js --timeout 15000 --exit",
20
20
  "test:mssql": "dotenv -e env/.env.mssql -- mocha test/adapters/mssql.*.test.js --timeout 30000 --exit",
21
21
  "test:properties": "mocha test/properties/*.property.test.js --timeout 30000 --exit",
22
- "test:all": "mocha test/adapters/*.test.js test/properties/*.property.test.js test/function.test.js --timeout 30000 --exit"
22
+ "test:all": "mocha test/adapters/*.test.js test/properties/*.property.test.js test/function.test.js --timeout 30000 --exit",
23
+ "demo:clear": "node -e \"var fs=require('fs'),p=require('path'),d=p.join(__dirname,'demo');fs.existsSync(d)&&fs.rmSync(d,{recursive:true,force:true});fs.mkdirSync(d,{recursive:true})\"",
24
+ "demo:create": "node scripts/demo-create.js"
23
25
  },
24
26
  "repository": {
25
27
  "type": "git",
@@ -27,6 +29,13 @@
27
29
  },
28
30
  "keywords": [
29
31
  "mysql2",
32
+ "sqlite3",
33
+ "oracledb",
34
+ "postgres",
35
+ "pg",
36
+ "dynamodb",
37
+ "mongodb",
38
+ "mssql",
30
39
  "express",
31
40
  "ultimate-express",
32
41
  "generative",
@@ -46,14 +55,14 @@
46
55
  "node-input-validator": "^4.5.0"
47
56
  },
48
57
  "peerDependencies": {
49
- "@aws-sdk/client-dynamodb": "^3.1029.0",
50
- "@aws-sdk/lib-dynamodb": "^3.1029.0",
58
+ "@aws-sdk/client-dynamodb": "^3.1039.0",
59
+ "@aws-sdk/lib-dynamodb": "^3.1039.0",
51
60
  "better-sqlite3": "^12.9.0",
52
61
  "express": "^4.17.2 || ^5.0.0",
53
62
  "ioredis": "^5.10.1",
54
- "mongodb": "^7.1.1",
55
- "mssql": "^12.2.1",
56
- "mysql2": "^3.14.4",
63
+ "mongodb": "^7.2.0",
64
+ "mssql": "^12.5.0",
65
+ "mysql2": "^3.22.3",
57
66
  "oracledb": "^6.10.0",
58
67
  "pg": "^8.20.0",
59
68
  "ultimate-express": "^2.0.0"
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const { execSync } = require("child_process");
7
+
8
+ const ROOT = path.resolve(__dirname, "..");
9
+ const DEMO = path.join(ROOT, "demo");
10
+
11
+ // 1. Clear demo folder
12
+ if (fs.existsSync(DEMO)) {
13
+ fs.rmSync(DEMO, { recursive: true, force: true });
14
+ }
15
+ fs.mkdirSync(DEMO, { recursive: true });
16
+
17
+ const run = (cmd, cwd) => {
18
+ console.log(`\n> ${cmd}`);
19
+ execSync(cmd, { cwd, stdio: "inherit" });
20
+ };
21
+
22
+ // 2. Scaffold project with sqlite3
23
+ run("node ../src/cli/main.js init --database sqlite3 --yes --no-install", DEMO);
24
+
25
+ // 3. Copy schema and patch adapter to sqlite3
26
+ const schema = JSON.parse(
27
+ fs.readFileSync(path.join(ROOT, "dbmr.schema.json"), "utf8"),
28
+ );
29
+ schema.adapter = "sqlite3";
30
+ if (schema.options) {
31
+ delete schema.options.session;
32
+ delete schema.options.loki;
33
+ }
34
+ fs.writeFileSync(
35
+ path.join(DEMO, "dbmr.schema.json"),
36
+ JSON.stringify(schema, null, 2) + "\n",
37
+ );
38
+ console.log("\n> Copied and patched dbmr.schema.json (adapter → sqlite3)");
39
+
40
+ // 4. Generate models, routes, tests, openapi from schema
41
+ run("node ../src/cli/main.js generate --from dbmr.schema.json", DEMO);
42
+
43
+ // 5. Install dependencies
44
+ run("npm install", DEMO);
45
+
46
+ console.log("\n✔ Demo project ready in ./demo");
47
+ console.log(" cd demo && npm run dev\n");