@mostajs/orm-bridge 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/CHANGELOG.md +42 -0
- package/LICENSE +29 -0
- package/README.md +203 -0
- package/dist/core/dialect-registry.d.ts +11 -0
- package/dist/core/dialect-registry.d.ts.map +1 -0
- package/dist/core/dialect-registry.js +58 -0
- package/dist/core/dialect-registry.js.map +1 -0
- package/dist/core/types.d.ts +44 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/prisma/dispatcher.d.ts +12 -0
- package/dist/prisma/dispatcher.d.ts.map +1 -0
- package/dist/prisma/dispatcher.js +102 -0
- package/dist/prisma/dispatcher.js.map +1 -0
- package/dist/prisma/extension.d.ts +24 -0
- package/dist/prisma/extension.d.ts.map +1 -0
- package/dist/prisma/extension.js +78 -0
- package/dist/prisma/extension.js.map +1 -0
- package/dist/prisma/index.d.ts +6 -0
- package/dist/prisma/index.d.ts.map +1 -0
- package/dist/prisma/index.js +8 -0
- package/dist/prisma/index.js.map +1 -0
- package/dist/prisma/mappers/orderby.d.ts +12 -0
- package/dist/prisma/mappers/orderby.d.ts.map +1 -0
- package/dist/prisma/mappers/orderby.js +33 -0
- package/dist/prisma/mappers/orderby.js.map +1 -0
- package/dist/prisma/mappers/where.d.ts +18 -0
- package/dist/prisma/mappers/where.d.ts.map +1 -0
- package/dist/prisma/mappers/where.js +136 -0
- package/dist/prisma/mappers/where.js.map +1 -0
- package/dist/prisma/types.d.ts +8 -0
- package/dist/prisma/types.d.ts.map +1 -0
- package/dist/prisma/types.js +4 -0
- package/dist/prisma/types.js.map +1 -0
- package/dist/utils/case-conversion.d.ts +7 -0
- package/dist/utils/case-conversion.d.ts.map +1 -0
- package/dist/utils/case-conversion.js +23 -0
- package/dist/utils/case-conversion.js.map +1 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@mostajs/orm-bridge` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-04-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Prisma Bridge** (`@mostajs/orm-bridge/prisma`) : runtime interception for Prisma Client via `$extends` API.
|
|
10
|
+
- **CRUD operations supported** :
|
|
11
|
+
- `findUnique`, `findUniqueOrThrow`
|
|
12
|
+
- `findFirst`, `findFirstOrThrow`
|
|
13
|
+
- `findMany` (with `where`, `orderBy`, `take`, `skip`)
|
|
14
|
+
- `count`
|
|
15
|
+
- `create`, `createMany`
|
|
16
|
+
- `update`, `updateMany`
|
|
17
|
+
- `upsert`
|
|
18
|
+
- `delete`, `deleteMany`
|
|
19
|
+
- **Where mapper** covers all major Prisma operators :
|
|
20
|
+
- equality (`equals`, shorthand field: value)
|
|
21
|
+
- comparison (`gt`, `gte`, `lt`, `lte`, `not`)
|
|
22
|
+
- sets (`in`, `notIn`)
|
|
23
|
+
- string ops (`contains`, `startsWith`, `endsWith` with `mode: 'insensitive'`)
|
|
24
|
+
- logical (`AND`, `OR`, `NOT`)
|
|
25
|
+
- **OrderBy mapper** : simple form + array form + nested sort objects
|
|
26
|
+
- **Lazy dialect registry** : caches connections by URI, idempotent schema init
|
|
27
|
+
- **Fallback mode** : unmapped models pass through to Prisma's default engine
|
|
28
|
+
- **Observability hook** (`onIntercept`) for logging/metrics
|
|
29
|
+
|
|
30
|
+
### Package structure
|
|
31
|
+
|
|
32
|
+
- `@mostajs/orm-bridge` — root (shared core)
|
|
33
|
+
- `@mostajs/orm-bridge/prisma` — Prisma-specific bridge (this release)
|
|
34
|
+
- Future sub-modules : `/drizzle`, `/typeorm`, `/mongoose` (v0.3+)
|
|
35
|
+
|
|
36
|
+
### Tests
|
|
37
|
+
|
|
38
|
+
28 integration tests on SQLite `:memory:` covering all supported operations.
|
|
39
|
+
|
|
40
|
+
### License
|
|
41
|
+
|
|
42
|
+
AGPL-3.0-or-later + commercial license option (drmdh@msn.com).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Dr Hamid MADANI <drmdh@msn.com>
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
COMMERCIAL LICENSE
|
|
20
|
+
|
|
21
|
+
For organizations that cannot comply with the AGPL open-source requirements,
|
|
22
|
+
a commercial license is available. Contact: drmdh@msn.com
|
|
23
|
+
|
|
24
|
+
The commercial license allows you to:
|
|
25
|
+
- Use the software in proprietary/closed-source projects
|
|
26
|
+
- Modify without publishing your source code
|
|
27
|
+
- Get priority support and SLA
|
|
28
|
+
|
|
29
|
+
Contact: Dr Hamid MADANI <drmdh@msn.com>
|
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# @mostajs/orm-bridge
|
|
2
|
+
|
|
3
|
+
> **Keep your Prisma code. Gain access to 13 databases.**
|
|
4
|
+
>
|
|
5
|
+
> Runtime bridges for third-party ORMs — intercept their calls and redirect them to [@mostajs/orm](https://github.com/apolocine/mosta-orm) without rewriting a single line of your existing code.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@mostajs/orm-bridge)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
## Why
|
|
11
|
+
|
|
12
|
+
Prisma supports **7 databases** (PostgreSQL, MySQL, SQLite, SQL Server, MongoDB, CockroachDB, MariaDB).
|
|
13
|
+
|
|
14
|
+
@mostajs/orm supports **13** (all of the above plus Oracle, DB2, HANA, HSQLDB, Spanner, Sybase — with more coming).
|
|
15
|
+
|
|
16
|
+
**This bridge lets you use Prisma's API on any of these 13 databases** — zero code change other than PrismaClient construction.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// Before
|
|
20
|
+
const prisma = new PrismaClient();
|
|
21
|
+
await prisma.user.findMany(); // only works on Prisma's 7 DBs
|
|
22
|
+
|
|
23
|
+
// After
|
|
24
|
+
const prisma = new PrismaClient({ datasourceUrl: 'sqlite::memory:' })
|
|
25
|
+
.$extends(mostaExtension({
|
|
26
|
+
models: {
|
|
27
|
+
User: { dialect: 'oracle', url: 'oracle://...', schema: UserSchema }
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
await prisma.user.findMany(); // now runs on Oracle!
|
|
32
|
+
// Full Prisma types preserved, zero other changes.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @mostajs/orm-bridge @mostajs/orm @prisma/client
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { PrismaClient } from '@prisma/client';
|
|
45
|
+
import { mostaExtension } from '@mostajs/orm-bridge/prisma';
|
|
46
|
+
import type { EntitySchema } from '@mostajs/orm';
|
|
47
|
+
|
|
48
|
+
const AuditLogSchema: EntitySchema = {
|
|
49
|
+
name: 'AuditLog',
|
|
50
|
+
collection: 'audit_logs',
|
|
51
|
+
fields: {
|
|
52
|
+
userId: { type: 'string', required: true },
|
|
53
|
+
action: { type: 'string', required: true },
|
|
54
|
+
timestamp: { type: 'date', required: true },
|
|
55
|
+
},
|
|
56
|
+
relations: {},
|
|
57
|
+
indexes: [{ fields: { userId: 'asc' } }],
|
|
58
|
+
timestamps: true,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const prisma = new PrismaClient({
|
|
62
|
+
datasourceUrl: 'sqlite::memory:', // no-op placeholder
|
|
63
|
+
}).$extends(mostaExtension({
|
|
64
|
+
models: {
|
|
65
|
+
AuditLog: {
|
|
66
|
+
dialect: 'mongodb',
|
|
67
|
+
url: process.env.MONGO_URL!,
|
|
68
|
+
schema: AuditLogSchema,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
onIntercept: (e) => console.log(`[bridge] ${e.model}.${e.operation} → ${e.dialect} (${e.duration}ms)`),
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
// Prisma → MongoDB via mosta-orm
|
|
75
|
+
await prisma.auditLog.create({
|
|
76
|
+
data: { userId: 'u1', action: 'login', timestamp: new Date() }
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const logs = await prisma.auditLog.findMany({
|
|
80
|
+
where: { userId: 'u1', timestamp: { gte: new Date('2026-01-01') } },
|
|
81
|
+
orderBy: { timestamp: 'desc' },
|
|
82
|
+
take: 10,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Other models NOT in config.models still go through Prisma's default engine
|
|
86
|
+
await prisma.user.findMany(); // unchanged behavior
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Architecture
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
┌────────────────────────┐
|
|
93
|
+
│ Your app (Prisma) │
|
|
94
|
+
│ prisma.user.findMany()│
|
|
95
|
+
└──────────┬──────────────┘
|
|
96
|
+
│
|
|
97
|
+
▼
|
|
98
|
+
┌────────────────────────┐
|
|
99
|
+
│ PrismaClient │
|
|
100
|
+
│ $extends($allModels) │
|
|
101
|
+
└──────────┬──────────────┘
|
|
102
|
+
│
|
|
103
|
+
┌─────┴──────┐
|
|
104
|
+
│ │
|
|
105
|
+
mapped? no
|
|
106
|
+
│ │
|
|
107
|
+
▼ ▼
|
|
108
|
+
mosta-orm Prisma default
|
|
109
|
+
dialect query engine
|
|
110
|
+
│
|
|
111
|
+
▼
|
|
112
|
+
┌──────────────────────┐
|
|
113
|
+
│ 13 databases │
|
|
114
|
+
│ PG / MySQL / Oracle │
|
|
115
|
+
│ MongoDB / DB2 / │
|
|
116
|
+
│ HANA / HSQLDB / │
|
|
117
|
+
│ Spanner / Sybase ...│
|
|
118
|
+
└──────────────────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Supported Prisma operations
|
|
122
|
+
|
|
123
|
+
| Operation | Supported | Notes |
|
|
124
|
+
|-----------|-----------|-------|
|
|
125
|
+
| `findUnique`, `findFirst`, `findUniqueOrThrow`, `findFirstOrThrow` | YES | Maps `where` to mosta FilterQuery |
|
|
126
|
+
| `findMany` | YES | Supports `where`, `orderBy`, `take`, `skip` |
|
|
127
|
+
| `count` | YES | |
|
|
128
|
+
| `create`, `createMany` | YES | |
|
|
129
|
+
| `update`, `updateMany` | YES | |
|
|
130
|
+
| `upsert` | YES | |
|
|
131
|
+
| `delete`, `deleteMany` | YES | |
|
|
132
|
+
| `aggregate`, `groupBy` | v0.2 | Planned |
|
|
133
|
+
| Nested `include` / `select` | v0.2 | Planned |
|
|
134
|
+
| Transactions | v0.3 | Planned |
|
|
135
|
+
|
|
136
|
+
## Supported Prisma `where` operators
|
|
137
|
+
|
|
138
|
+
| Prisma | mosta-orm |
|
|
139
|
+
|--------|-----------|
|
|
140
|
+
| `{ field: value }` | direct equals |
|
|
141
|
+
| `equals` | `$eq` |
|
|
142
|
+
| `not` | `$ne` |
|
|
143
|
+
| `gt`, `gte`, `lt`, `lte` | `$gt`, `$gte`, `$lt`, `$lte` |
|
|
144
|
+
| `in`, `notIn` | `$in`, `$nin` |
|
|
145
|
+
| `contains` | `$regex` (escaped) |
|
|
146
|
+
| `startsWith`, `endsWith` | `$regex` (anchored) |
|
|
147
|
+
| `mode: 'insensitive'` | `$regexFlags: 'i'` |
|
|
148
|
+
| `AND`, `OR` | `$and`, `$or` |
|
|
149
|
+
| `NOT` | best-effort condition inversion |
|
|
150
|
+
|
|
151
|
+
## Configuration reference
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
interface PrismaBridgeConfig {
|
|
155
|
+
/** Model name → mosta-orm binding */
|
|
156
|
+
models: Record<string, ModelBinding>;
|
|
157
|
+
|
|
158
|
+
/** What to do when a model is not mapped (default: 'source') */
|
|
159
|
+
fallback?: 'source' | 'error';
|
|
160
|
+
|
|
161
|
+
/** Observability hook */
|
|
162
|
+
onIntercept?: (event: InterceptEvent) => void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface ModelBinding {
|
|
166
|
+
dialect: DialectType; // 'postgres', 'mongodb', 'oracle', ...
|
|
167
|
+
url?: string; // connection URI
|
|
168
|
+
connection?: ConnectionConfig; // full config alternative
|
|
169
|
+
collection?: string; // override table name
|
|
170
|
+
schema?: EntitySchema; // mosta-orm schema (recommended)
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Roadmap
|
|
175
|
+
|
|
176
|
+
- **v0.1.0** — Prisma bridge MVP (CRUD + filters + orderBy) ✅
|
|
177
|
+
- **v0.2.0** — aggregate / groupBy / nested include / transactions
|
|
178
|
+
- **v0.3.0** — Drizzle bridge (same pattern for Drizzle ORM)
|
|
179
|
+
- **v0.4.0** — TypeORM bridge
|
|
180
|
+
- **v0.5.0** — Mongoose bridge
|
|
181
|
+
|
|
182
|
+
## How it works
|
|
183
|
+
|
|
184
|
+
We use Prisma's official [`$extends`](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query) API — a stable extension point. The `$allOperations` handler intercepts every model call and decides whether to:
|
|
185
|
+
|
|
186
|
+
- **Forward to mosta-orm** (if the model is in `config.models`) — runs the query on the mapped dialect, returning the result in Prisma's expected shape.
|
|
187
|
+
- **Pass through to Prisma** (otherwise) — normal Prisma behavior.
|
|
188
|
+
|
|
189
|
+
No monkey-patching. No Prisma internals hacked. Works with Prisma 5.4+ (including the new rust-free `prisma-client` generator in Prisma 6.16+).
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
**AGPL-3.0-or-later** + commercial license available.
|
|
194
|
+
|
|
195
|
+
For commercial use in closed-source projects, contact: drmdh@msn.com
|
|
196
|
+
|
|
197
|
+
## Author
|
|
198
|
+
|
|
199
|
+
Dr Hamid MADANI <drmdh@msn.com>
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
Part of the [@mostajs ecosystem](https://github.com/apolocine) — 13 databases, 11 transports, one unified backend.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type IDialect } from '@mostajs/orm';
|
|
2
|
+
import type { ModelBinding } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get (or create) a dialect instance for the given binding.
|
|
5
|
+
* Caches by URI so the same connection is reused across calls.
|
|
6
|
+
* Also lazily runs initSchema for each schema registered on the binding.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getOrCreateDialect(binding: ModelBinding): Promise<IDialect>;
|
|
9
|
+
/** Close all cached dialects (useful for tests/graceful shutdown) */
|
|
10
|
+
export declare function disposeAllDialects(): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=dialect-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialect-registry.d.ts","sourceRoot":"","sources":["../../src/core/dialect-registry.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,QAAQ,EAAyB,MAAM,cAAc,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyBjF;AAiBD,qEAAqE;AACrE,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUxD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// dialect-registry.ts
|
|
2
|
+
// Lazy-initializes and caches mosta-orm dialects per model binding.
|
|
3
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
+
import { getDialect } from '@mostajs/orm';
|
|
5
|
+
const cache = new Map();
|
|
6
|
+
const schemasInit = new Set(); // key = dialectKey + schema.name
|
|
7
|
+
/**
|
|
8
|
+
* Get (or create) a dialect instance for the given binding.
|
|
9
|
+
* Caches by URI so the same connection is reused across calls.
|
|
10
|
+
* Also lazily runs initSchema for each schema registered on the binding.
|
|
11
|
+
*/
|
|
12
|
+
export async function getOrCreateDialect(binding) {
|
|
13
|
+
const key = cacheKey(binding);
|
|
14
|
+
if (!cache.has(key)) {
|
|
15
|
+
cache.set(key, initDialect(binding));
|
|
16
|
+
}
|
|
17
|
+
let dialect;
|
|
18
|
+
try {
|
|
19
|
+
dialect = await cache.get(key);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
cache.delete(key);
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
// Idempotent schema init : run once per (connection, schema)
|
|
26
|
+
if (binding.schema) {
|
|
27
|
+
const schemaKey = key + '::' + binding.schema.name;
|
|
28
|
+
if (!schemasInit.has(schemaKey)) {
|
|
29
|
+
await dialect.initSchema([binding.schema]);
|
|
30
|
+
schemasInit.add(schemaKey);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return dialect;
|
|
34
|
+
}
|
|
35
|
+
async function initDialect(binding) {
|
|
36
|
+
const config = binding.connection ?? {
|
|
37
|
+
dialect: binding.dialect,
|
|
38
|
+
uri: binding.url ?? '',
|
|
39
|
+
};
|
|
40
|
+
if (!config.dialect)
|
|
41
|
+
config.dialect = binding.dialect;
|
|
42
|
+
const dialect = await getDialect(config);
|
|
43
|
+
return dialect;
|
|
44
|
+
}
|
|
45
|
+
function cacheKey(b) {
|
|
46
|
+
return `${b.dialect}::${b.url ?? b.connection?.uri ?? 'custom-conn'}`;
|
|
47
|
+
}
|
|
48
|
+
/** Close all cached dialects (useful for tests/graceful shutdown) */
|
|
49
|
+
export async function disposeAllDialects() {
|
|
50
|
+
const entries = [...cache.values()];
|
|
51
|
+
cache.clear();
|
|
52
|
+
schemasInit.clear();
|
|
53
|
+
const dialects = await Promise.all(entries.map(p => p.catch(() => null)));
|
|
54
|
+
await Promise.all(dialects
|
|
55
|
+
.filter((d) => d !== null)
|
|
56
|
+
.map(d => d.disconnect().catch(() => null)));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=dialect-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialect-registry.js","sourceRoot":"","sources":["../../src/core/dialect-registry.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,oEAAoE;AACpE,wCAAwC;AAExC,OAAO,EAAE,UAAU,EAAwC,MAAM,cAAc,CAAC;AAGhF,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC,CAAE,iCAAiC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAqB;IAC5D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QACnD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAqB;IAC9C,MAAM,MAAM,GAAqB,OAAO,CAAC,UAAU,IAAI;QACrD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;KACvB,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEtD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAe;IAC/B,OAAO,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,aAAa,EAAE,CAAC;AACxE,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,WAAW,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ;SACL,MAAM,CAAC,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SACxC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAC9C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DialectType, ConnectionConfig, EntitySchema } from '@mostajs/orm';
|
|
2
|
+
/**
|
|
3
|
+
* Per-model binding configuration.
|
|
4
|
+
* Tells the bridge which @mostajs/orm dialect backs each foreign-ORM model.
|
|
5
|
+
*/
|
|
6
|
+
export interface ModelBinding {
|
|
7
|
+
/** Dialect name (e.g. 'postgres', 'mongodb', 'oracle') */
|
|
8
|
+
dialect: DialectType;
|
|
9
|
+
/** Connection URL or URI */
|
|
10
|
+
url?: string;
|
|
11
|
+
/** Full connection config (alternative to url) */
|
|
12
|
+
connection?: ConnectionConfig;
|
|
13
|
+
/** Optional collection/table name override (defaults to snake_case + plural of model name) */
|
|
14
|
+
collection?: string;
|
|
15
|
+
/** Optional EntitySchema pre-built (skip schema inference) */
|
|
16
|
+
schema?: EntitySchema;
|
|
17
|
+
}
|
|
18
|
+
/** Common bridge configuration shared by all source ORMs */
|
|
19
|
+
export interface BridgeConfig {
|
|
20
|
+
/**
|
|
21
|
+
* Map of model name → mosta-orm binding.
|
|
22
|
+
* Models NOT listed here fall back to the source ORM's default engine.
|
|
23
|
+
*/
|
|
24
|
+
models: Record<string, ModelBinding>;
|
|
25
|
+
/**
|
|
26
|
+
* Behavior when a model is not mapped :
|
|
27
|
+
* - 'source' (default): let the source ORM handle the query normally
|
|
28
|
+
* - 'error': throw an error
|
|
29
|
+
*/
|
|
30
|
+
fallback?: 'source' | 'error';
|
|
31
|
+
/**
|
|
32
|
+
* Hook called for every intercepted operation, for logging/metrics.
|
|
33
|
+
*/
|
|
34
|
+
onIntercept?: (event: InterceptEvent) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface InterceptEvent {
|
|
37
|
+
source: string;
|
|
38
|
+
model: string;
|
|
39
|
+
operation: string;
|
|
40
|
+
dialect: DialectType;
|
|
41
|
+
duration?: number;
|
|
42
|
+
error?: Error;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,OAAO,EAAE,WAAW,CAAC;IAErB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,kDAAkD;IAClD,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B,8FAA8F;IAC9F,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAErC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAE9B;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,wCAAwC;AACxC,6BAA6B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { BridgeConfig, ModelBinding, InterceptEvent } from './core/types.js';
|
|
2
|
+
export { getOrCreateDialect, disposeAllDialects } from './core/dialect-registry.js';
|
|
3
|
+
export { modelToCollection, pascalToCamel, toPascalCase } from './utils/case-conversion.js';
|
|
4
|
+
export { mostaExtension, dispatchPrismaOp, mapPrismaWhere, mapPrismaOrderBy, } from './prisma/index.js';
|
|
5
|
+
export type { PrismaBridgeConfig, PrismaOperation, } from './prisma/types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK5F,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @mostajs/orm-bridge — Root public API
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// License: AGPL-3.0-or-later
|
|
4
|
+
export { getOrCreateDialect, disposeAllDialects } from './core/dialect-registry.js';
|
|
5
|
+
export { modelToCollection, pascalToCamel, toPascalCase } from './utils/case-conversion.js';
|
|
6
|
+
// --- Prisma bridge (primary sub-module) ---
|
|
7
|
+
// Prefer `import { mostaExtension } from '@mostajs/orm-bridge/prisma'` for
|
|
8
|
+
// better tree-shaking and explicit intent.
|
|
9
|
+
export { mostaExtension, dispatchPrismaOp, mapPrismaWhere, mapPrismaOrderBy, } from './prisma/index.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,wCAAwC;AACxC,6BAA6B;AAI7B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE5F,6CAA6C;AAC7C,2EAA2E;AAC3E,2CAA2C;AAC3C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IDialect } from '@mostajs/orm';
|
|
2
|
+
import type { ModelBinding } from '../core/types.js';
|
|
3
|
+
import type { PrismaOperation } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Execute a Prisma operation on a mosta-orm dialect.
|
|
6
|
+
* Returns data shaped to match Prisma's expected return contract.
|
|
7
|
+
*
|
|
8
|
+
* Requires `binding.schema` to be set — if absent, builds a minimal
|
|
9
|
+
* schema from the model name (best-effort; may fail on exotic fields).
|
|
10
|
+
*/
|
|
11
|
+
export declare function dispatchPrismaOp(dialect: IDialect, binding: ModelBinding, modelName: string, operation: PrismaOperation, args: Record<string, unknown> | undefined): Promise<unknown>;
|
|
12
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/prisma/dispatcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,OAAO,CAAC,OAAO,CAAC,CAkFlB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Prisma dispatcher : route Prisma operations to @mostajs/orm dialect methods
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// License: AGPL-3.0-or-later
|
|
4
|
+
import { mapPrismaWhere } from './mappers/where.js';
|
|
5
|
+
import { mapPrismaOrderBy } from './mappers/orderby.js';
|
|
6
|
+
import { modelToCollection } from '../utils/case-conversion.js';
|
|
7
|
+
/**
|
|
8
|
+
* Execute a Prisma operation on a mosta-orm dialect.
|
|
9
|
+
* Returns data shaped to match Prisma's expected return contract.
|
|
10
|
+
*
|
|
11
|
+
* Requires `binding.schema` to be set — if absent, builds a minimal
|
|
12
|
+
* schema from the model name (best-effort; may fail on exotic fields).
|
|
13
|
+
*/
|
|
14
|
+
export async function dispatchPrismaOp(dialect, binding, modelName, operation, args) {
|
|
15
|
+
const schema = resolveSchema(binding, modelName);
|
|
16
|
+
const a = args ?? {};
|
|
17
|
+
const where = 'where' in a ? mapPrismaWhere(a.where) : {};
|
|
18
|
+
const sort = 'orderBy' in a ? mapPrismaOrderBy(a.orderBy) : undefined;
|
|
19
|
+
const limit = typeof a.take === 'number' ? a.take : undefined;
|
|
20
|
+
const skip = typeof a.skip === 'number' ? a.skip : undefined;
|
|
21
|
+
const queryOpts = { sort, limit, skip };
|
|
22
|
+
switch (operation) {
|
|
23
|
+
case 'findUnique':
|
|
24
|
+
case 'findFirst':
|
|
25
|
+
return dialect.findOne(schema, where);
|
|
26
|
+
case 'findUniqueOrThrow':
|
|
27
|
+
case 'findFirstOrThrow': {
|
|
28
|
+
const res = await dialect.findOne(schema, where);
|
|
29
|
+
if (!res)
|
|
30
|
+
throw new Error(`${modelName} not found (where=${JSON.stringify(where)})`);
|
|
31
|
+
return res;
|
|
32
|
+
}
|
|
33
|
+
case 'findMany':
|
|
34
|
+
return dialect.find(schema, where, queryOpts);
|
|
35
|
+
case 'count':
|
|
36
|
+
return dialect.count(schema, where);
|
|
37
|
+
case 'create':
|
|
38
|
+
return dialect.create(schema, (a.data ?? {}));
|
|
39
|
+
case 'createMany': {
|
|
40
|
+
const rows = Array.isArray(a.data) ? a.data : [a.data];
|
|
41
|
+
let count = 0;
|
|
42
|
+
for (const row of rows) {
|
|
43
|
+
await dialect.create(schema, row);
|
|
44
|
+
count++;
|
|
45
|
+
}
|
|
46
|
+
return { count };
|
|
47
|
+
}
|
|
48
|
+
case 'update': {
|
|
49
|
+
const existing = await dialect.findOne(schema, where);
|
|
50
|
+
if (!existing)
|
|
51
|
+
throw new Error(`${modelName} not found for update`);
|
|
52
|
+
const id = String(existing.id ?? existing._id ?? '');
|
|
53
|
+
return dialect.update(schema, id, a.data);
|
|
54
|
+
}
|
|
55
|
+
case 'updateMany': {
|
|
56
|
+
const count = await dialect.updateMany(schema, where, a.data);
|
|
57
|
+
return { count };
|
|
58
|
+
}
|
|
59
|
+
case 'upsert': {
|
|
60
|
+
const existing = await dialect.findOne(schema, where);
|
|
61
|
+
if (existing) {
|
|
62
|
+
const id = String(existing.id ?? existing._id ?? '');
|
|
63
|
+
return dialect.update(schema, id, a.update);
|
|
64
|
+
}
|
|
65
|
+
return dialect.create(schema, a.create);
|
|
66
|
+
}
|
|
67
|
+
case 'delete': {
|
|
68
|
+
const existing = await dialect.findOne(schema, where);
|
|
69
|
+
if (!existing)
|
|
70
|
+
throw new Error(`${modelName} not found for delete`);
|
|
71
|
+
const id = String(existing.id ?? existing._id ?? '');
|
|
72
|
+
await dialect.delete(schema, id);
|
|
73
|
+
return existing;
|
|
74
|
+
}
|
|
75
|
+
case 'deleteMany': {
|
|
76
|
+
const count = await dialect.deleteMany(schema, where);
|
|
77
|
+
return { count };
|
|
78
|
+
}
|
|
79
|
+
case 'aggregate':
|
|
80
|
+
case 'groupBy':
|
|
81
|
+
default:
|
|
82
|
+
throw new Error(`Prisma operation "${operation}" not yet supported by @mostajs/orm-bridge v0.1. Planned for v0.2.0.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve the EntitySchema for this model.
|
|
87
|
+
* Prefers binding.schema ; else constructs a permissive minimal schema.
|
|
88
|
+
*/
|
|
89
|
+
function resolveSchema(binding, modelName) {
|
|
90
|
+
if (binding.schema)
|
|
91
|
+
return binding.schema;
|
|
92
|
+
// Minimal permissive schema — useful for read-only / pass-through use cases
|
|
93
|
+
return {
|
|
94
|
+
name: modelName,
|
|
95
|
+
collection: binding.collection ?? modelToCollection(modelName),
|
|
96
|
+
fields: {},
|
|
97
|
+
relations: {},
|
|
98
|
+
indexes: [],
|
|
99
|
+
timestamps: false,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/prisma/dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PrismaBridgeConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a Prisma Client `$extends` object that intercepts model operations
|
|
4
|
+
* and redirects them to @mostajs/orm for any model listed in `config.models`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { PrismaClient } from '@prisma/client';
|
|
9
|
+
* import { mostaExtension } from '@mostajs/orm-bridge/prisma';
|
|
10
|
+
*
|
|
11
|
+
* const prisma = new PrismaClient({ datasourceUrl: 'sqlite::memory:' })
|
|
12
|
+
* .$extends(mostaExtension({
|
|
13
|
+
* models: {
|
|
14
|
+
* AuditLog: { dialect: 'mongodb', url: process.env.MONGO_URL },
|
|
15
|
+
* Inventory: { dialect: 'oracle', url: process.env.ORACLE_URL },
|
|
16
|
+
* },
|
|
17
|
+
* }));
|
|
18
|
+
*
|
|
19
|
+
* // prisma.auditLog.findMany() → executed by @mostajs/orm on MongoDB
|
|
20
|
+
* // prisma.user.findMany() → still handled by Prisma default engine (if not mapped)
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function mostaExtension(config: PrismaBridgeConfig): any;
|
|
24
|
+
//# sourceMappingURL=extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../src/prisma/extension.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,YAAY,CAAC;AAItE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,OA+DxD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Prisma Client $extends factory — main public API for Prisma Bridge
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// License: AGPL-3.0-or-later
|
|
4
|
+
import { getOrCreateDialect } from '../core/dialect-registry.js';
|
|
5
|
+
import { dispatchPrismaOp } from './dispatcher.js';
|
|
6
|
+
/**
|
|
7
|
+
* Build a Prisma Client `$extends` object that intercepts model operations
|
|
8
|
+
* and redirects them to @mostajs/orm for any model listed in `config.models`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { PrismaClient } from '@prisma/client';
|
|
13
|
+
* import { mostaExtension } from '@mostajs/orm-bridge/prisma';
|
|
14
|
+
*
|
|
15
|
+
* const prisma = new PrismaClient({ datasourceUrl: 'sqlite::memory:' })
|
|
16
|
+
* .$extends(mostaExtension({
|
|
17
|
+
* models: {
|
|
18
|
+
* AuditLog: { dialect: 'mongodb', url: process.env.MONGO_URL },
|
|
19
|
+
* Inventory: { dialect: 'oracle', url: process.env.ORACLE_URL },
|
|
20
|
+
* },
|
|
21
|
+
* }));
|
|
22
|
+
*
|
|
23
|
+
* // prisma.auditLog.findMany() → executed by @mostajs/orm on MongoDB
|
|
24
|
+
* // prisma.user.findMany() → still handled by Prisma default engine (if not mapped)
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function mostaExtension(config) {
|
|
28
|
+
const fallback = config.fallback ?? 'source';
|
|
29
|
+
/**
|
|
30
|
+
* Return type is deliberately `any` because the structural shape matches
|
|
31
|
+
* Prisma's `defineExtension` input without requiring a hard import
|
|
32
|
+
* of @prisma/client types (optional peer dependency).
|
|
33
|
+
*/
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
const extension = {
|
|
36
|
+
name: 'mosta-orm-bridge',
|
|
37
|
+
query: {
|
|
38
|
+
$allModels: {
|
|
39
|
+
async $allOperations({ model, operation, args, query }) {
|
|
40
|
+
const binding = model ? config.models[model] : undefined;
|
|
41
|
+
if (!binding) {
|
|
42
|
+
if (fallback === 'error') {
|
|
43
|
+
throw new Error(`[@mostajs/orm-bridge] Model "${model}" is not mapped to a mosta-orm dialect. ` +
|
|
44
|
+
`Add it to config.models, or set fallback: 'source' to let Prisma handle it.`);
|
|
45
|
+
}
|
|
46
|
+
return query(args); // let Prisma handle the query normally
|
|
47
|
+
}
|
|
48
|
+
const started = Date.now();
|
|
49
|
+
try {
|
|
50
|
+
const dialect = await getOrCreateDialect(binding);
|
|
51
|
+
const result = await dispatchPrismaOp(dialect, binding, model, operation, args);
|
|
52
|
+
config.onIntercept?.({
|
|
53
|
+
source: 'prisma',
|
|
54
|
+
model,
|
|
55
|
+
operation,
|
|
56
|
+
dialect: binding.dialect,
|
|
57
|
+
duration: Date.now() - started,
|
|
58
|
+
});
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
config.onIntercept?.({
|
|
63
|
+
source: 'prisma',
|
|
64
|
+
model,
|
|
65
|
+
operation,
|
|
66
|
+
dialect: binding.dialect,
|
|
67
|
+
duration: Date.now() - started,
|
|
68
|
+
error: err,
|
|
69
|
+
});
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return extension;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../src/prisma/extension.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wCAAwC;AACxC,6BAA6B;AAG7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,MAA0B;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAE7C;;;;OAIG;IACH,8DAA8D;IAC9D,MAAM,SAAS,GAAQ;QACrB,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAMnD;oBACC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;4BACzB,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,0CAA0C;gCAC/E,6EAA6E,CAC9E,CAAC;wBACJ,CAAC;wBACD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,uCAAuC;oBAC9D,CAAC;oBAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC3B,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;wBAClD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAA4B,EAAE,IAAI,CAC5D,CAAC;wBACF,MAAM,CAAC,WAAW,EAAE,CAAC;4BACnB,MAAM,EAAE,QAAQ;4BAChB,KAAK;4BACL,SAAS;4BACT,OAAO,EAAE,OAAO,CAAC,OAAO;4BACxB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;yBAC/B,CAAC,CAAC;wBACH,OAAO,MAAM,CAAC;oBAChB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,WAAW,EAAE,CAAC;4BACnB,MAAM,EAAE,QAAQ;4BAChB,KAAK;4BACL,SAAS;4BACT,OAAO,EAAE,OAAO,CAAC,OAAO;4BACxB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;4BAC9B,KAAK,EAAE,GAAY;yBACpB,CAAC,CAAC;wBACH,MAAM,GAAG,CAAC;oBACZ,CAAC;gBACH,CAAC;aACF;SACF;KACF,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { mostaExtension } from './extension.js';
|
|
2
|
+
export { dispatchPrismaOp } from './dispatcher.js';
|
|
3
|
+
export { mapPrismaWhere } from './mappers/where.js';
|
|
4
|
+
export { mapPrismaOrderBy } from './mappers/orderby.js';
|
|
5
|
+
export type { PrismaBridgeConfig, PrismaOperation, ModelBinding } from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prisma/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Prisma sub-module public API
|
|
2
|
+
// Usage: import { mostaExtension } from '@mostajs/orm-bridge/prisma'
|
|
3
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
+
export { mostaExtension } from './extension.js';
|
|
5
|
+
export { dispatchPrismaOp } from './dispatcher.js';
|
|
6
|
+
export { mapPrismaWhere } from './mappers/where.js';
|
|
7
|
+
export { mapPrismaOrderBy } from './mappers/orderby.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prisma/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,qEAAqE;AACrE,wCAAwC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SortDirection } from '@mostajs/orm';
|
|
2
|
+
/**
|
|
3
|
+
* Convert Prisma `orderBy` to mosta-orm QueryOptions.sort.
|
|
4
|
+
*
|
|
5
|
+
* Prisma accepts :
|
|
6
|
+
* - { field: 'asc' | 'desc' }
|
|
7
|
+
* - [{ field: 'asc' }, { other: 'desc' }]
|
|
8
|
+
* - { field: { sort: 'asc', nulls: 'first' } } — nulls ignored in v0.1
|
|
9
|
+
* - { relation: { field: 'asc' } } — flattened to dotted path
|
|
10
|
+
*/
|
|
11
|
+
export declare function mapPrismaOrderBy(orderBy: unknown): Record<string, SortDirection> | undefined;
|
|
12
|
+
//# sourceMappingURL=orderby.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orderby.d.ts","sourceRoot":"","sources":["../../../src/prisma/mappers/orderby.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,CAsB5F"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Prisma orderBy → @mostajs/orm sort
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
/**
|
|
4
|
+
* Convert Prisma `orderBy` to mosta-orm QueryOptions.sort.
|
|
5
|
+
*
|
|
6
|
+
* Prisma accepts :
|
|
7
|
+
* - { field: 'asc' | 'desc' }
|
|
8
|
+
* - [{ field: 'asc' }, { other: 'desc' }]
|
|
9
|
+
* - { field: { sort: 'asc', nulls: 'first' } } — nulls ignored in v0.1
|
|
10
|
+
* - { relation: { field: 'asc' } } — flattened to dotted path
|
|
11
|
+
*/
|
|
12
|
+
export function mapPrismaOrderBy(orderBy) {
|
|
13
|
+
if (!orderBy)
|
|
14
|
+
return undefined;
|
|
15
|
+
const out = {};
|
|
16
|
+
const entries = Array.isArray(orderBy)
|
|
17
|
+
? orderBy.flatMap(o => Object.entries(o))
|
|
18
|
+
: Object.entries(orderBy);
|
|
19
|
+
for (const [key, val] of entries) {
|
|
20
|
+
if (typeof val === 'string') {
|
|
21
|
+
out[key] = val === 'desc' ? -1 : 1;
|
|
22
|
+
}
|
|
23
|
+
else if (val && typeof val === 'object') {
|
|
24
|
+
const v = val;
|
|
25
|
+
if (v.sort === 'asc' || v.sort === 'desc') {
|
|
26
|
+
out[key] = v.sort === 'desc' ? -1 : 1;
|
|
27
|
+
}
|
|
28
|
+
// nested relation: skip for now (not trivial without schema info)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=orderby.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orderby.js","sourceRoot":"","sources":["../../../src/prisma/mappers/orderby.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,wCAAwC;AAIxC;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,MAAM,GAAG,GAAkC,EAAE,CAAC;IAE9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACpC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAA4B,CAAC,CAAC;QACpE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAkC,CAAC,CAAC;IAEvD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,GAAwB,CAAC;YACnC,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YACD,kEAAkE;QACpE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FilterQuery } from '@mostajs/orm';
|
|
2
|
+
/**
|
|
3
|
+
* Convert Prisma `where` argument into mosta-orm FilterQuery.
|
|
4
|
+
*
|
|
5
|
+
* Supported :
|
|
6
|
+
* - equals: { field: value } or { field: { equals: value } }
|
|
7
|
+
* - Basic comparison : { gt, gte, lt, lte, not, in, notIn }
|
|
8
|
+
* - String ops : { contains, startsWith, endsWith, mode: 'insensitive' }
|
|
9
|
+
* - Logical : AND, OR, NOT
|
|
10
|
+
* - Nested : { relation: { field: value } } — flattened to dotted path (best effort)
|
|
11
|
+
*
|
|
12
|
+
* Not supported (v0.1) :
|
|
13
|
+
* - has, hasSome, hasEvery (array membership)
|
|
14
|
+
* - path/JSON filters
|
|
15
|
+
* - Relation filters with complex nesting
|
|
16
|
+
*/
|
|
17
|
+
export declare function mapPrismaWhere(where: unknown): FilterQuery;
|
|
18
|
+
//# sourceMappingURL=where.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"where.d.ts","sourceRoot":"","sources":["../../../src/prisma/mappers/where.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,cAAc,CAAC;AAEhE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAgC1D"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Prisma where clause → @mostajs/orm FilterQuery
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
/**
|
|
4
|
+
* Convert Prisma `where` argument into mosta-orm FilterQuery.
|
|
5
|
+
*
|
|
6
|
+
* Supported :
|
|
7
|
+
* - equals: { field: value } or { field: { equals: value } }
|
|
8
|
+
* - Basic comparison : { gt, gte, lt, lte, not, in, notIn }
|
|
9
|
+
* - String ops : { contains, startsWith, endsWith, mode: 'insensitive' }
|
|
10
|
+
* - Logical : AND, OR, NOT
|
|
11
|
+
* - Nested : { relation: { field: value } } — flattened to dotted path (best effort)
|
|
12
|
+
*
|
|
13
|
+
* Not supported (v0.1) :
|
|
14
|
+
* - has, hasSome, hasEvery (array membership)
|
|
15
|
+
* - path/JSON filters
|
|
16
|
+
* - Relation filters with complex nesting
|
|
17
|
+
*/
|
|
18
|
+
export function mapPrismaWhere(where) {
|
|
19
|
+
if (!where || typeof where !== 'object')
|
|
20
|
+
return {};
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const [key, value] of Object.entries(where)) {
|
|
23
|
+
if (key === 'AND') {
|
|
24
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
25
|
+
out.$and = arr.map(v => mapPrismaWhere(v));
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (key === 'OR') {
|
|
29
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
30
|
+
out.$or = arr.map(v => mapPrismaWhere(v));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (key === 'NOT') {
|
|
34
|
+
// Best-effort: use $and with inverted ops — simplified to shallow
|
|
35
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
36
|
+
for (const v of arr) {
|
|
37
|
+
const inverted = mapPrismaWhere(v);
|
|
38
|
+
for (const [field, condition] of Object.entries(inverted)) {
|
|
39
|
+
if (field.startsWith('$'))
|
|
40
|
+
continue;
|
|
41
|
+
out[field] = negateCondition(condition);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
out[key] = mapValueOrCondition(value);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
function mapValueOrCondition(value) {
|
|
51
|
+
// Primitive → equals
|
|
52
|
+
if (value === null ||
|
|
53
|
+
typeof value === 'string' ||
|
|
54
|
+
typeof value === 'number' ||
|
|
55
|
+
typeof value === 'boolean' ||
|
|
56
|
+
value instanceof Date) {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
// Array — could be $in implicit (some Prisma patterns)
|
|
60
|
+
if (Array.isArray(value))
|
|
61
|
+
return value;
|
|
62
|
+
if (value && typeof value === 'object') {
|
|
63
|
+
return mapOperatorObject(value);
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
function mapOperatorObject(obj) {
|
|
68
|
+
const op = {};
|
|
69
|
+
if ('equals' in obj)
|
|
70
|
+
op.$eq = obj.equals;
|
|
71
|
+
if ('not' in obj)
|
|
72
|
+
op.$ne = obj.not;
|
|
73
|
+
if ('gt' in obj)
|
|
74
|
+
op.$gt = obj.gt;
|
|
75
|
+
if ('gte' in obj)
|
|
76
|
+
op.$gte = obj.gte;
|
|
77
|
+
if ('lt' in obj)
|
|
78
|
+
op.$lt = obj.lt;
|
|
79
|
+
if ('lte' in obj)
|
|
80
|
+
op.$lte = obj.lte;
|
|
81
|
+
if ('in' in obj)
|
|
82
|
+
op.$in = obj.in;
|
|
83
|
+
if ('notIn' in obj)
|
|
84
|
+
op.$nin = obj.notIn;
|
|
85
|
+
// String operators → regex
|
|
86
|
+
const caseInsensitive = (obj.mode === 'insensitive');
|
|
87
|
+
if ('contains' in obj) {
|
|
88
|
+
op.$regex = escapeRegex(String(obj.contains));
|
|
89
|
+
if (caseInsensitive)
|
|
90
|
+
op.$regexFlags = 'i';
|
|
91
|
+
}
|
|
92
|
+
if ('startsWith' in obj) {
|
|
93
|
+
op.$regex = '^' + escapeRegex(String(obj.startsWith));
|
|
94
|
+
if (caseInsensitive)
|
|
95
|
+
op.$regexFlags = 'i';
|
|
96
|
+
}
|
|
97
|
+
if ('endsWith' in obj) {
|
|
98
|
+
op.$regex = escapeRegex(String(obj.endsWith)) + '$';
|
|
99
|
+
if (caseInsensitive)
|
|
100
|
+
op.$regexFlags = 'i';
|
|
101
|
+
}
|
|
102
|
+
// If no operator keys matched, return original (probably a nested relation filter)
|
|
103
|
+
if (Object.keys(op).length === 0) {
|
|
104
|
+
return obj;
|
|
105
|
+
}
|
|
106
|
+
return op;
|
|
107
|
+
}
|
|
108
|
+
function negateCondition(condition) {
|
|
109
|
+
if (typeof condition === 'object' && condition !== null) {
|
|
110
|
+
// Best-effort swap : $eq ↔ $ne, $in ↔ $nin, $gt ↔ $lte, $gte ↔ $lt
|
|
111
|
+
const c = condition;
|
|
112
|
+
const n = {};
|
|
113
|
+
if ('$eq' in c)
|
|
114
|
+
n.$ne = c.$eq;
|
|
115
|
+
if ('$ne' in c)
|
|
116
|
+
n.$eq = c.$ne;
|
|
117
|
+
if ('$in' in c)
|
|
118
|
+
n.$nin = c.$in;
|
|
119
|
+
if ('$nin' in c)
|
|
120
|
+
n.$in = c.$nin;
|
|
121
|
+
if ('$gt' in c)
|
|
122
|
+
n.$lte = c.$gt;
|
|
123
|
+
if ('$gte' in c)
|
|
124
|
+
n.$lt = c.$gte;
|
|
125
|
+
if ('$lt' in c)
|
|
126
|
+
n.$gte = c.$lt;
|
|
127
|
+
if ('$lte' in c)
|
|
128
|
+
n.$gt = c.$lte;
|
|
129
|
+
return n;
|
|
130
|
+
}
|
|
131
|
+
return { $ne: condition };
|
|
132
|
+
}
|
|
133
|
+
function escapeRegex(s) {
|
|
134
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=where.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"where.js","sourceRoot":"","sources":["../../../src/prisma/mappers/where.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,wCAAwC;AAIxC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,MAAM,GAAG,GAAgB,EAAE,CAAC;IAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACnD,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACnD,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,kEAAkE;YAClE,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACnD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBACnC,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1D,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;wBAAE,SAAS;oBACpC,GAAG,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,GAAG,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,qBAAqB;IACrB,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS;QAC1B,KAAK,YAAY,IAAI,EACrB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,iBAAiB,CAAC,KAAgC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,GAA4B;IACrD,MAAM,EAAE,GAAmB,EAAE,CAAC;IAE9B,IAAI,QAAQ,IAAI,GAAG;QAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACzC,IAAI,KAAK,IAAO,GAAG;QAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACtC,IAAI,IAAI,IAAQ,GAAG;QAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;IACrC,IAAI,KAAK,IAAO,GAAG;QAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;IACvC,IAAI,IAAI,IAAQ,GAAG;QAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;IACrC,IAAI,KAAK,IAAO,GAAG;QAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;IACvC,IAAI,IAAI,IAAQ,GAAG;QAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,EAAe,CAAC;IAClD,IAAI,OAAO,IAAK,GAAG;QAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,KAAkB,CAAC;IAEtD,2BAA2B;IAC3B,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACrD,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;QACtB,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,IAAI,eAAe;YAAE,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IAC5C,CAAC;IACD,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;QACxB,EAAE,CAAC,MAAM,GAAG,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QACtD,IAAI,eAAe;YAAE,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IAC5C,CAAC;IACD,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;QACtB,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC;QACpD,IAAI,eAAe;YAAE,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IAC5C,CAAC;IAED,mFAAmF;IACnF,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,eAAe,CAAC,SAAkB;IACzC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACxD,mEAAmE;QACnE,MAAM,CAAC,GAAG,SAA2B,CAAC;QACtC,MAAM,CAAC,GAAmB,EAAE,CAAC;QAC7B,IAAI,KAAK,IAAK,CAAC;YAAE,CAAC,CAAC,GAAG,GAAI,CAAC,CAAC,GAAG,CAAC;QAChC,IAAI,KAAK,IAAK,CAAC;YAAE,CAAC,CAAC,GAAG,GAAI,CAAC,CAAC,GAAG,CAAC;QAChC,IAAI,KAAK,IAAK,CAAC;YAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;QAChC,IAAI,MAAM,IAAI,CAAC;YAAE,CAAC,CAAC,GAAG,GAAI,CAAC,CAAC,IAAI,CAAC;QACjC,IAAI,KAAK,IAAK,CAAC;YAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;QAChC,IAAI,MAAM,IAAI,CAAC;YAAE,CAAC,CAAC,GAAG,GAAI,CAAC,CAAC,IAAI,CAAC;QACjC,IAAI,KAAK,IAAK,CAAC;YAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;QAChC,IAAI,MAAM,IAAI,CAAC;YAAE,CAAC,CAAC,GAAG,GAAI,CAAC,CAAC,IAAI,CAAC;QACjC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BridgeConfig, ModelBinding } from '../core/types.js';
|
|
2
|
+
export interface PrismaBridgeConfig extends BridgeConfig {
|
|
3
|
+
/** (optional) override default fallback to 'prisma' */
|
|
4
|
+
fallback?: 'source' | 'error';
|
|
5
|
+
}
|
|
6
|
+
export type PrismaOperation = 'findUnique' | 'findUniqueOrThrow' | 'findFirst' | 'findFirstOrThrow' | 'findMany' | 'count' | 'create' | 'createMany' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'deleteMany' | 'aggregate' | 'groupBy';
|
|
7
|
+
export type { ModelBinding };
|
|
8
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prisma/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,uDAAuD;IACvD,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,MAAM,eAAe,GACvB,YAAY,GAAG,mBAAmB,GAClC,WAAW,GAAI,kBAAkB,GACjC,UAAU,GACV,OAAO,GACP,QAAQ,GAAO,YAAY,GAC3B,QAAQ,GAAO,YAAY,GAC3B,QAAQ,GACR,QAAQ,GAAO,YAAY,GAC3B,WAAW,GAAI,SAAS,CAAC;AAE7B,YAAY,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/prisma/types.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wCAAwC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** PascalCase (User) to snake_case plural (users) — naive pluralization */
|
|
2
|
+
export declare function modelToCollection(modelName: string): string;
|
|
3
|
+
/** PascalCase (User) to camelCase (user) */
|
|
4
|
+
export declare function pascalToCamel(modelName: string): string;
|
|
5
|
+
/** camelCase or PascalCase to PascalCase */
|
|
6
|
+
export declare function toPascalCase(name: string): string;
|
|
7
|
+
//# sourceMappingURL=case-conversion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-conversion.d.ts","sourceRoot":"","sources":["../../src/utils/case-conversion.ts"],"names":[],"mappings":"AAGA,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// case-conversion.ts
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
/** PascalCase (User) to snake_case plural (users) — naive pluralization */
|
|
4
|
+
export function modelToCollection(modelName) {
|
|
5
|
+
const snake = modelName
|
|
6
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
7
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
8
|
+
.toLowerCase();
|
|
9
|
+
if (/(s|x|z|ch|sh)$/.test(snake))
|
|
10
|
+
return snake + 'es';
|
|
11
|
+
if (/[^aeiou]y$/.test(snake))
|
|
12
|
+
return snake.slice(0, -1) + 'ies';
|
|
13
|
+
return snake + 's';
|
|
14
|
+
}
|
|
15
|
+
/** PascalCase (User) to camelCase (user) */
|
|
16
|
+
export function pascalToCamel(modelName) {
|
|
17
|
+
return modelName.charAt(0).toLowerCase() + modelName.slice(1);
|
|
18
|
+
}
|
|
19
|
+
/** camelCase or PascalCase to PascalCase */
|
|
20
|
+
export function toPascalCase(name) {
|
|
21
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=case-conversion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-conversion.js","sourceRoot":"","sources":["../../src/utils/case-conversion.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,wCAAwC;AAExC,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,KAAK,GAAG,SAAS;SACpB,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,WAAW,EAAE,CAAC;IACjB,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,GAAG,IAAI,CAAC;IACtD,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAChE,OAAO,KAAK,GAAG,GAAG,CAAC;AACrB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mostajs/orm-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Runtime bridges for third-party ORMs (Prisma, Drizzle, TypeORM, Mongoose) — intercept their calls and redirect to @mostajs/orm for 13-database access without rewriting existing code",
|
|
5
|
+
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
|
+
"license": "AGPL-3.0-or-later",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./prisma": {
|
|
17
|
+
"types": "./dist/prisma/index.d.ts",
|
|
18
|
+
"import": "./dist/prisma/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": ["dist", "LICENSE", "README.md", "CHANGELOG.md"],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"dev": "tsc --watch",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"test": "npx tsx test-scripts/run-all.ts",
|
|
27
|
+
"test:prisma": "npx tsx test-scripts/test-prisma-bridge.ts",
|
|
28
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"mostajs",
|
|
32
|
+
"orm",
|
|
33
|
+
"bridge",
|
|
34
|
+
"prisma",
|
|
35
|
+
"drizzle",
|
|
36
|
+
"typeorm",
|
|
37
|
+
"mongoose",
|
|
38
|
+
"interception",
|
|
39
|
+
"runtime",
|
|
40
|
+
"proxy",
|
|
41
|
+
"multi-database",
|
|
42
|
+
"mongodb",
|
|
43
|
+
"oracle",
|
|
44
|
+
"db2"
|
|
45
|
+
],
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/apolocine/mosta-orm-bridge.git"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/apolocine/mosta-orm-bridge/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/apolocine/mosta-orm-bridge#readme",
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@mostajs/orm": "^1.9.0",
|
|
56
|
+
"@prisma/client": ">=5.4.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"@prisma/client": { "optional": true }
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@mostajs/orm": "^1.9.0",
|
|
63
|
+
"@prisma/client": "^5.20.0",
|
|
64
|
+
"@types/node": "^20.0.0",
|
|
65
|
+
"prisma": "^5.20.0",
|
|
66
|
+
"tsx": "^4.0.0",
|
|
67
|
+
"typescript": "^5.3.0",
|
|
68
|
+
"better-sqlite3": "^11.0.0"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=18.0.0"
|
|
72
|
+
}
|
|
73
|
+
}
|