@mostajs/net 1.0.0-alpha.1 → 1.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/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # MostaNet
2
+
3
+ > **Multi-protocol transport layer for @mostajs/orm** — expose your entities via 11+ protocols.
4
+ > REST, GraphQL, WebSocket, SSE, JSON-RPC, MCP, and more.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@mostajs/net.svg)](https://www.npmjs.com/package/@mostajs/net)
7
+ [![license](https://img.shields.io/npm/l/@mostajs/net.svg)](LICENSE)
8
+
9
+ ---
10
+
11
+ ## What is MostaNet?
12
+
13
+ MostaNet mirrors the **IDialect adapter pattern** of @mostajs/orm for the transport layer. Where ORM dialects abstract *where* data is stored (13 databases), transport adapters abstract *how* data is exposed (11+ protocols).
14
+
15
+ ```
16
+ Client request → ITransport → OrmRequest → EntityService → IDialect → Database
17
+
18
+ OrmResponse → ITransport → Client response
19
+ ```
20
+
21
+ One `EntitySchema`, 13 databases, 11+ protocols = **143+ combinations**.
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - **6 transports implemented** — REST, GraphQL, WebSocket, SSE, JSON-RPC, MCP
28
+ - **5 planned** — gRPC, tRPC, OData, NATS, Arrow Flight
29
+ - **API Key management** — generate, revoke, validate with 3D permission matrix (key x SGBD x protocol)
30
+ - **Middleware pipeline** — logging, auth, rate-limiting, CORS
31
+ - **CLI** — `npx @mostajs/net serve` to start the server
32
+ - **Fastify-based** — high-performance HTTP server
33
+ - **MCP transport** — AI agents (Claude, GPT) can query any database via MCP protocol
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ npm install @mostajs/orm @mostajs/net
41
+ ```
42
+
43
+ ### 1. Define schemas
44
+
45
+ ```typescript
46
+ // schemas/user.ts
47
+ import type { EntitySchema } from '@mostajs/orm'
48
+
49
+ export const UserSchema: EntitySchema = {
50
+ name: 'User',
51
+ collection: 'users',
52
+ fields: {
53
+ name: { type: 'string', required: true },
54
+ email: { type: 'string', required: true, unique: true },
55
+ role: { type: 'string', default: 'user' },
56
+ },
57
+ relations: {},
58
+ indexes: [{ fields: { email: 'asc' }, unique: true }],
59
+ timestamps: true,
60
+ }
61
+ ```
62
+
63
+ ### 2. Configure .env.local
64
+
65
+ ```bash
66
+ # Database
67
+ DB_DIALECT=postgres
68
+ SGBD_URI=postgresql://user:pass@localhost:5432/mydb
69
+ DB_SCHEMA_STRATEGY=update
70
+
71
+ # Transports
72
+ MOSTA_NET_REST_ENABLED=true
73
+ MOSTA_NET_REST_PORT=3000
74
+ MOSTA_NET_GRAPHQL_ENABLED=true
75
+ MOSTA_NET_WS_ENABLED=true
76
+ MOSTA_NET_SSE_ENABLED=true
77
+ MOSTA_NET_JSONRPC_ENABLED=true
78
+ MOSTA_NET_MCP_ENABLED=true
79
+
80
+ # Logging (from @mostajs/orm)
81
+ DB_SHOW_SQL=true
82
+ DB_FORMAT_SQL=true
83
+ DB_HIGHLIGHT_SQL=true
84
+ DB_POOL_SIZE=20
85
+ ```
86
+
87
+ ### 3. Start the server
88
+
89
+ ```bash
90
+ npx @mostajs/net serve
91
+ ```
92
+
93
+ Or programmatically :
94
+
95
+ ```typescript
96
+ import { startServer } from '@mostajs/net'
97
+
98
+ await startServer({
99
+ schemas: [UserSchema],
100
+ port: 3000,
101
+ })
102
+ ```
103
+
104
+ ### 4. Use it
105
+
106
+ ```bash
107
+ # REST
108
+ curl http://localhost:3000/api/v1/users
109
+ curl -X POST http://localhost:3000/api/v1/users -d '{"name":"Dr Madani","email":"drmdh@msn.com"}'
110
+
111
+ # GraphQL
112
+ curl -X POST http://localhost:3000/graphql -d '{"query":"{ users { id name email } }"}'
113
+
114
+ # JSON-RPC
115
+ curl -X POST http://localhost:3000/rpc -d '{"jsonrpc":"2.0","method":"User.findAll","id":1}'
116
+
117
+ # WebSocket
118
+ wscat -c ws://localhost:3000/ws
119
+ > {"op":"findAll","entity":"User"}
120
+
121
+ # MCP (via Claude/GPT agent)
122
+ # Tools: User_findAll, User_create, User_count, etc.
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Transports
128
+
129
+ | Transport | Protocol | Status | Use case |
130
+ |-----------|----------|--------|----------|
131
+ | **RestTransport** | HTTP REST | ✅ Production | Universal API (7 routes per entity) |
132
+ | **GraphQLTransport** | GraphQL | ✅ Production | Flexible queries, auto-generated schema |
133
+ | **WebSocketTransport** | WebSocket | ✅ Production | Bidirectional, real-time |
134
+ | **SSETransport** | Server-Sent Events | ✅ Production | Real-time broadcast (entity.created/updated/deleted) |
135
+ | **JsonRpcTransport** | JSON-RPC 2.0 | ✅ Production | Batch requests, method discovery |
136
+ | **McpTransport** | Model Context Protocol | ✅ Production | AI agents (Claude, GPT, Copilot) |
137
+ | GrpcTransport | gRPC | Planned | Service-to-service |
138
+ | TrpcTransport | tRPC | Planned | End-to-end type safety |
139
+ | ODataTransport | OData | Planned | Enterprise integration |
140
+ | NatsTransport | NATS | Planned | Message queue |
141
+ | ArrowFlightTransport | Arrow Flight | Planned | Analytics, big data |
142
+
143
+ ---
144
+
145
+ ## API Key Management
146
+
147
+ ```bash
148
+ # Generate a key
149
+ npx @mostajs/net generate-apikey "My App" live
150
+
151
+ # List keys
152
+ npx @mostajs/net list-keys
153
+
154
+ # Revoke a key
155
+ npx @mostajs/net revoke-key "My App"
156
+ ```
157
+
158
+ Keys are stored in `.mosta/apikeys.json` with bcrypt hashes and a 3D permission matrix (API key x database x transport x operation).
159
+
160
+ ---
161
+
162
+ ## Architecture
163
+
164
+ ```
165
+ @mostajs/net (this package)
166
+ ↓ depends on
167
+ @mostajs/orm (13 databases)
168
+ ↓ managed by
169
+ @mostajs/ornetadmin (admin UI)
170
+ ```
171
+
172
+ - **net depends on orm** (unidirectional)
173
+ - **orm has zero transport dependencies**
174
+ - **ornetadmin writes config files** that orm and net read
175
+
176
+ ---
177
+
178
+ ## CLI Commands
179
+
180
+ | Command | Description |
181
+ |---------|-------------|
182
+ | `npx @mostajs/net serve` | Start the transport server |
183
+ | `npx @mostajs/net info` | Show config, transports, API keys |
184
+ | `npx @mostajs/net generate-apikey <name> [live\|test]` | Generate an API key |
185
+ | `npx @mostajs/net list-keys` | List all API keys |
186
+ | `npx @mostajs/net revoke-key <name>` | Revoke an API key |
187
+ | `npx @mostajs/net hash-password <password>` | Hash a password (SHA-256) |
188
+
189
+ ---
190
+
191
+ ## License
192
+
193
+ MIT — © 2025-2026 Dr Hamid MADANI <drmdh@msn.com>
194
+
195
+ ## Contributing
196
+
197
+ Issues and PRs welcome at [github.com/apolocine/mosta-net](https://github.com/apolocine/mosta-net).
package/dist/cli.js CHANGED
File without changes
package/dist/server.js CHANGED
@@ -31,8 +31,46 @@ export async function startServer() {
31
31
  const entityService = new EntityService(dialect);
32
32
  // 4. Get schemas
33
33
  const schemas = getAllSchemas();
34
- // 5. Create shared Fastify instance
34
+ // 5. Display startup banner
35
+ const C = { reset: '\x1b[0m', dim: '\x1b[2m', cyan: '\x1b[36m', green: '\x1b[32m', yellow: '\x1b[33m', magenta: '\x1b[35m', gray: '\x1b[90m', blue: '\x1b[34m' };
36
+ const maskedUri = (process.env.SGBD_URI || '').replace(/:([^@]+)@/, ':***@');
37
+ console.log(`
38
+ ${C.cyan}┌─────────────────────────────────────────────────────┐${C.reset}
39
+ ${C.cyan}│${C.reset} ${C.cyan}@mostajs/net${C.reset} ${C.cyan}│${C.reset}
40
+ ${C.cyan}│${C.reset} Dialect: ${C.green}${process.env.DB_DIALECT || 'unknown'}${C.reset} ${C.dim}(${maskedUri})${C.reset}
41
+ ${C.cyan}│${C.reset} Entities: ${C.green}${schemas.map(s => s.name).join(', ')}${C.reset} ${C.dim}(${schemas.length})${C.reset}
42
+ ${C.cyan}│${C.reset} Port: ${C.yellow}${config.port}${C.reset}
43
+ ${C.cyan}│${C.reset} Show SQL: ${process.env.DB_SHOW_SQL === 'true' ? C.green + 'true' : C.gray + 'false'}${C.reset} Format: ${process.env.DB_FORMAT_SQL === 'true' ? C.green + 'true' : C.gray + 'false'}${C.reset} Highlight: ${process.env.DB_HIGHLIGHT_SQL === 'true' ? C.green + 'true' : C.gray + 'false'}${C.reset}
44
+ ${C.cyan}│${C.reset} Pool: ${C.yellow}${process.env.DB_POOL_SIZE || '10'}${C.reset} Strategy: ${C.yellow}${process.env.DB_SCHEMA_STRATEGY || 'none'}${C.reset}
45
+ ${C.cyan}│${C.reset} Transports: ${C.green}${getEnabledTransports(config).join(', ')}${C.reset} ${C.dim}(${getEnabledTransports(config).length})${C.reset}
46
+ ${C.cyan}└─────────────────────────────────────────────────────┘${C.reset}
47
+ `);
48
+ // 5b. Create shared Fastify instance
35
49
  const app = Fastify({ logger: false });
50
+ // 5c. Request logger — log each transaction to terminal
51
+ app.addHook('onResponse', (req, reply, done) => {
52
+ const ms = reply.elapsedTime?.toFixed(0) || '?';
53
+ const status = reply.statusCode;
54
+ const method = req.method;
55
+ const url = req.url;
56
+ // Detect transport from URL
57
+ let transport = 'HTTP';
58
+ if (url.startsWith('/api/v1/'))
59
+ transport = 'REST';
60
+ else if (url.startsWith('/graphql'))
61
+ transport = 'GraphQL';
62
+ else if (url.startsWith('/rpc'))
63
+ transport = 'JSON-RPC';
64
+ else if (url.startsWith('/ws'))
65
+ transport = 'WS';
66
+ else if (url.startsWith('/events'))
67
+ transport = 'SSE';
68
+ else if (url.startsWith('/mcp'))
69
+ transport = 'MCP';
70
+ const statusColor = status < 300 ? C.green : status < 400 ? C.yellow : C.magenta;
71
+ console.log(`${C.dim}[NET:${C.cyan}${transport}${C.dim}]${C.reset} ${C.blue}${method}${C.reset} ${url} ${statusColor}${status}${C.reset} ${C.gray}(${ms}ms)${C.reset}`);
72
+ done();
73
+ });
36
74
  // 6. ORM handler (OrmRequest → EntityService → OrmResponse)
37
75
  const ormHandler = async (req, _ctx) => {
38
76
  return entityService.execute(req);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/net",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0",
4
4
  "description": "Multi-protocol transport layer for @mostajs/orm — expose entities via REST, gRPC, GraphQL, WebSocket, SSE, tRPC, MCP, OData, Arrow Flight, JSON-RPC, NATS",
5
5
  "author": "Dr Hamid MADANI <drmdh@msn.com>",
6
6
  "license": "MIT",