@promakeai/orm 1.0.0 → 1.0.3
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 +368 -63
- package/dist/adapters/IDataAdapter.d.ts +4 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +113 -8
- package/dist/schema/fieldBuilder.d.ts +37 -1
- package/dist/types.d.ts +23 -2
- package/dist/utils/deserializer.d.ts +24 -0
- package/dist/utils/whereBuilder.d.ts +1 -0
- package/package.json +3 -2
- package/src/ORM.ts +14 -5
- package/src/adapters/IDataAdapter.ts +5 -0
- package/src/index.ts +7 -0
- package/src/schema/fieldBuilder.ts +50 -1
- package/src/schema/schemaHelpers.ts +2 -1
- package/src/types.ts +39 -2
- package/src/utils/deserializer.ts +92 -0
- package/src/utils/jsonConverter.ts +40 -1
- package/src/utils/populateResolver.ts +2 -1
- package/src/utils/whereBuilder.ts +17 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @promakeai/orm
|
|
2
2
|
|
|
3
|
-
Core ORM package with schema DSL, query builder, and multi-language support.
|
|
3
|
+
Core ORM package with schema DSL, query builder, and multi-language support. Platform-agnostic - works in both browser and Node.js.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -15,29 +15,36 @@ import { defineSchema, f } from '@promakeai/orm';
|
|
|
15
15
|
|
|
16
16
|
const schema = defineSchema({
|
|
17
17
|
name: 'myapp',
|
|
18
|
-
languages: ['en', 'tr'],
|
|
19
|
-
defaultLanguage: 'en',
|
|
18
|
+
languages: ['en', 'tr', 'de'],
|
|
20
19
|
tables: {
|
|
21
20
|
users: {
|
|
22
21
|
id: f.id(),
|
|
23
|
-
email: f.string().required().unique(),
|
|
24
|
-
name: f.string().required(),
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
email: f.string().required().unique().lowercase(),
|
|
23
|
+
name: f.string().required().trim(),
|
|
24
|
+
age: f.int().min(0).max(150),
|
|
25
|
+
role: f.string().enum(['user', 'admin']).default('user'),
|
|
26
|
+
bio: f.text().translatable(),
|
|
27
|
+
createdAt: f.timestamp(),
|
|
28
|
+
metadata: f.json(),
|
|
27
29
|
},
|
|
28
30
|
products: {
|
|
29
31
|
id: f.id(),
|
|
30
32
|
sku: f.string().required().unique(),
|
|
31
|
-
price: f.decimal().required(),
|
|
33
|
+
price: f.decimal().required().min(0),
|
|
32
34
|
stock: f.int().default(0),
|
|
33
|
-
name: f.string().translatable(),
|
|
34
|
-
description: f.text().translatable(),
|
|
35
|
-
categoryId: f.int().ref('categories'),
|
|
35
|
+
name: f.string().translatable().required(),
|
|
36
|
+
description: f.text().translatable(),
|
|
37
|
+
categoryId: f.int().ref('categories'),
|
|
38
|
+
tagIds: f.json().ref('tags'), // Array reference
|
|
36
39
|
},
|
|
37
40
|
categories: {
|
|
38
41
|
id: f.id(),
|
|
39
42
|
slug: f.string().required().unique(),
|
|
40
|
-
name: f.string().translatable(),
|
|
43
|
+
name: f.string().translatable().required(),
|
|
44
|
+
parentId: f.int().ref({
|
|
45
|
+
table: 'categories',
|
|
46
|
+
onDelete: 'SET_NULL',
|
|
47
|
+
}),
|
|
41
48
|
},
|
|
42
49
|
},
|
|
43
50
|
});
|
|
@@ -45,109 +52,407 @@ const schema = defineSchema({
|
|
|
45
52
|
|
|
46
53
|
## Field Types
|
|
47
54
|
|
|
48
|
-
| Type | Description |
|
|
49
|
-
|
|
50
|
-
| `f.id()` | Auto-increment primary key |
|
|
51
|
-
| `f.string()` | Short text |
|
|
52
|
-
| `f.text()` | Long text |
|
|
53
|
-
| `f.int()` | Integer |
|
|
54
|
-
| `f.decimal()` | Decimal number |
|
|
55
|
-
| `f.bool()` | Boolean |
|
|
56
|
-
| `f.timestamp()` | ISO datetime |
|
|
57
|
-
| `f.json()` | JSON data |
|
|
55
|
+
| Type | SQL | Description |
|
|
56
|
+
|------|-----|-------------|
|
|
57
|
+
| `f.id()` | INTEGER PRIMARY KEY AUTOINCREMENT | Auto-increment primary key |
|
|
58
|
+
| `f.string()` | VARCHAR | Short text |
|
|
59
|
+
| `f.text()` | TEXT | Long text |
|
|
60
|
+
| `f.int()` | INTEGER | Integer |
|
|
61
|
+
| `f.decimal()` | REAL/DECIMAL | Decimal number |
|
|
62
|
+
| `f.bool()` | INTEGER (0/1) | Boolean |
|
|
63
|
+
| `f.timestamp()` | TEXT (ISO) | ISO datetime string |
|
|
64
|
+
| `f.json()` | TEXT | JSON serialized data |
|
|
58
65
|
|
|
59
66
|
## Field Modifiers
|
|
60
67
|
|
|
68
|
+
### Constraints
|
|
69
|
+
|
|
61
70
|
```typescript
|
|
62
71
|
f.string()
|
|
63
72
|
.required() // NOT NULL
|
|
73
|
+
.nullable() // Allow NULL (default)
|
|
64
74
|
.unique() // UNIQUE constraint
|
|
65
|
-
.
|
|
75
|
+
.primary() // PRIMARY KEY
|
|
76
|
+
.default('value') // DEFAULT value
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### String Transforms
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
f.string()
|
|
83
|
+
.trim() // Remove whitespace
|
|
84
|
+
.lowercase() // Convert to lowercase
|
|
85
|
+
.uppercase() // Convert to uppercase
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Validation
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
f.string()
|
|
92
|
+
.minLength(1) // Minimum length
|
|
93
|
+
.maxLength(255) // Maximum length
|
|
66
94
|
.enum(['a', 'b', 'c']) // Allowed values
|
|
67
|
-
.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.
|
|
95
|
+
.match(/^[a-z]+$/) // RegExp pattern
|
|
96
|
+
|
|
97
|
+
f.int()
|
|
98
|
+
.min(0) // Minimum value
|
|
99
|
+
.max(100) // Maximum value
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### References
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Simple reference
|
|
106
|
+
f.int().ref('users')
|
|
107
|
+
|
|
108
|
+
// With options
|
|
109
|
+
f.int().ref({
|
|
110
|
+
table: 'users',
|
|
111
|
+
field: 'id', // Default: 'id'
|
|
112
|
+
onDelete: 'CASCADE', // CASCADE | SET_NULL | RESTRICT | NO_ACTION
|
|
113
|
+
onUpdate: 'CASCADE',
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// Array reference (JSON field with refs)
|
|
117
|
+
f.json().ref('tags')
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Multi-Language
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
f.string().translatable() // Stored in {table}_translations
|
|
124
|
+
f.text().translatable()
|
|
71
125
|
```
|
|
72
126
|
|
|
73
127
|
## Query Builder (MongoDB-style)
|
|
74
128
|
|
|
75
129
|
```typescript
|
|
76
|
-
import {
|
|
130
|
+
import { buildWhereClause } from '@promakeai/orm';
|
|
77
131
|
|
|
78
132
|
// Simple equality
|
|
79
|
-
|
|
80
|
-
// WHERE status = 'active'
|
|
133
|
+
buildWhereClause({ status: 'active' });
|
|
134
|
+
// WHERE status = ? params: ['active']
|
|
81
135
|
|
|
82
136
|
// Comparison operators
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
137
|
+
buildWhereClause({ price: { $gt: 100 } }); // > 100
|
|
138
|
+
buildWhereClause({ price: { $gte: 100 } }); // >= 100
|
|
139
|
+
buildWhereClause({ price: { $lt: 100 } }); // < 100
|
|
140
|
+
buildWhereClause({ price: { $lte: 100 } }); // <= 100
|
|
141
|
+
buildWhereClause({ status: { $ne: 'deleted' } }); // != 'deleted'
|
|
88
142
|
|
|
89
143
|
// Array operators
|
|
90
|
-
|
|
91
|
-
|
|
144
|
+
buildWhereClause({ id: { $in: [1, 2, 3] } }); // IN (?, ?, ?)
|
|
145
|
+
buildWhereClause({ id: { $nin: [1, 2, 3] } }); // NOT IN (?, ?, ?)
|
|
92
146
|
|
|
93
147
|
// String matching
|
|
94
|
-
|
|
95
|
-
|
|
148
|
+
buildWhereClause({ name: { $like: '%john%' } }); // LIKE ?
|
|
149
|
+
buildWhereClause({ name: { $notLike: '%test%' } }); // NOT LIKE ?
|
|
96
150
|
|
|
97
151
|
// Range and null
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
152
|
+
buildWhereClause({ price: { $between: [10, 100] } }); // BETWEEN ? AND ?
|
|
153
|
+
buildWhereClause({ deletedAt: { $isNull: true } }); // IS NULL
|
|
154
|
+
buildWhereClause({ email: { $isNull: false } }); // IS NOT NULL
|
|
101
155
|
|
|
102
156
|
// Logical operators
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
157
|
+
buildWhereClause({
|
|
158
|
+
$or: [
|
|
159
|
+
{ active: true },
|
|
160
|
+
{ role: 'admin' }
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
// (active = ? OR role = ?)
|
|
164
|
+
|
|
165
|
+
buildWhereClause({
|
|
166
|
+
$and: [
|
|
167
|
+
{ price: { $gt: 50 } },
|
|
168
|
+
{ stock: { $gt: 0 } }
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
// (price > ? AND stock > ?)
|
|
172
|
+
|
|
173
|
+
buildWhereClause({
|
|
174
|
+
$nor: [
|
|
175
|
+
{ banned: true },
|
|
176
|
+
{ suspended: true }
|
|
177
|
+
]
|
|
178
|
+
});
|
|
179
|
+
// NOT (banned = ? OR suspended = ?)
|
|
180
|
+
|
|
181
|
+
// Negation
|
|
182
|
+
buildWhereClause({
|
|
183
|
+
age: { $not: { $lt: 18 } }
|
|
184
|
+
});
|
|
185
|
+
// NOT (age < ?)
|
|
186
|
+
|
|
187
|
+
// Combined
|
|
188
|
+
buildWhereClause({
|
|
189
|
+
status: 'active',
|
|
190
|
+
price: { $gt: 100, $lt: 500 },
|
|
191
|
+
category: { $in: ['electronics', 'books'] },
|
|
192
|
+
});
|
|
193
|
+
// status = ? AND price > ? AND price < ? AND category IN (?, ?)
|
|
106
194
|
```
|
|
107
195
|
|
|
108
196
|
## Multi-Language Support
|
|
109
197
|
|
|
110
|
-
Schema
|
|
198
|
+
### Schema Configuration
|
|
111
199
|
|
|
112
200
|
```typescript
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
201
|
+
const schema = defineSchema({
|
|
202
|
+
languages: ['en', 'tr', 'de'], // Supported languages
|
|
203
|
+
// OR
|
|
204
|
+
languages: {
|
|
205
|
+
default: 'en',
|
|
206
|
+
supported: ['en', 'tr', 'de'],
|
|
207
|
+
},
|
|
208
|
+
tables: {
|
|
209
|
+
products: {
|
|
210
|
+
id: f.id(),
|
|
211
|
+
price: f.decimal(),
|
|
212
|
+
name: f.string().translatable(), // In translation table
|
|
213
|
+
description: f.text().translatable(), // In translation table
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Generated Tables
|
|
220
|
+
|
|
221
|
+
```sql
|
|
222
|
+
-- Main table
|
|
223
|
+
CREATE TABLE products (
|
|
224
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
225
|
+
price REAL
|
|
226
|
+
);
|
|
120
227
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
228
|
+
-- Translation table
|
|
229
|
+
CREATE TABLE products_translations (
|
|
230
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
231
|
+
product_id INTEGER NOT NULL,
|
|
232
|
+
lang TEXT NOT NULL,
|
|
233
|
+
name TEXT,
|
|
234
|
+
description TEXT,
|
|
235
|
+
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE,
|
|
236
|
+
UNIQUE (product_id, lang)
|
|
237
|
+
);
|
|
124
238
|
```
|
|
125
239
|
|
|
126
|
-
Query
|
|
240
|
+
### Translation Query Builder
|
|
127
241
|
|
|
128
242
|
```typescript
|
|
129
|
-
|
|
243
|
+
import { buildTranslationQuery } from '@promakeai/orm';
|
|
244
|
+
|
|
245
|
+
const { sql, params } = buildTranslationQuery('products', schema, {
|
|
130
246
|
lang: 'tr',
|
|
131
|
-
fallbackLang: 'en',
|
|
247
|
+
fallbackLang: 'en',
|
|
248
|
+
where: { price: { $gt: 100 } },
|
|
249
|
+
orderBy: [{ field: 'name', direction: 'ASC' }],
|
|
250
|
+
limit: 10,
|
|
132
251
|
});
|
|
252
|
+
|
|
253
|
+
// SELECT
|
|
254
|
+
// m.id, m.price,
|
|
255
|
+
// COALESCE(t.name, fb.name) AS name,
|
|
256
|
+
// COALESCE(t.description, fb.description) AS description
|
|
257
|
+
// FROM products m
|
|
258
|
+
// LEFT JOIN products_translations t ON m.id = t.product_id AND t.lang = ?
|
|
259
|
+
// LEFT JOIN products_translations fb ON m.id = fb.product_id AND fb.lang = ?
|
|
260
|
+
// WHERE price > ?
|
|
261
|
+
// ORDER BY name ASC
|
|
262
|
+
// LIMIT 10
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Populate Resolver
|
|
266
|
+
|
|
267
|
+
Batch-fetches references to prevent N+1 queries:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { resolvePopulate } from '@promakeai/orm';
|
|
271
|
+
|
|
272
|
+
const posts = await adapter.list('posts');
|
|
273
|
+
|
|
274
|
+
// Resolve author references
|
|
275
|
+
const postsWithAuthors = await resolvePopulate(
|
|
276
|
+
posts,
|
|
277
|
+
{ userId: true },
|
|
278
|
+
schema,
|
|
279
|
+
adapter
|
|
280
|
+
);
|
|
281
|
+
// [{ id: 1, title: '...', userId: { id: 1, name: 'John' } }]
|
|
282
|
+
|
|
283
|
+
// Nested populate
|
|
284
|
+
const postsWithDetails = await resolvePopulate(
|
|
285
|
+
posts,
|
|
286
|
+
{
|
|
287
|
+
userId: true,
|
|
288
|
+
comments: {
|
|
289
|
+
populate: { authorId: true },
|
|
290
|
+
where: { approved: true },
|
|
291
|
+
limit: 5,
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
schema,
|
|
295
|
+
adapter
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
// Array reference populate
|
|
299
|
+
const postsWithTags = await resolvePopulate(
|
|
300
|
+
posts,
|
|
301
|
+
{ tagIds: true }, // JSON array of tag IDs
|
|
302
|
+
schema,
|
|
303
|
+
adapter
|
|
304
|
+
);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Schema Helpers
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import {
|
|
311
|
+
getTranslatableFields,
|
|
312
|
+
getNonTranslatableFields,
|
|
313
|
+
getReferenceFields,
|
|
314
|
+
getPrimaryKeyField,
|
|
315
|
+
getRequiredFields,
|
|
316
|
+
isRequiredField,
|
|
317
|
+
getMainTableFields,
|
|
318
|
+
getTranslationTableFields,
|
|
319
|
+
toTranslationTableName,
|
|
320
|
+
toTranslationFKName,
|
|
321
|
+
singularize,
|
|
322
|
+
pluralize,
|
|
323
|
+
toPascalCase,
|
|
324
|
+
toCamelCase,
|
|
325
|
+
toSnakeCase,
|
|
326
|
+
} from '@promakeai/orm';
|
|
327
|
+
|
|
328
|
+
const table = schema.tables.products;
|
|
329
|
+
|
|
330
|
+
getTranslatableFields(table); // ['name', 'description']
|
|
331
|
+
getNonTranslatableFields(table); // ['id', 'price', 'sku', 'stock', 'categoryId']
|
|
332
|
+
getReferenceFields(table); // [['categoryId', { table: 'categories', ... }]]
|
|
333
|
+
getPrimaryKeyField(table); // 'id'
|
|
334
|
+
getRequiredFields(table); // ['sku', 'price', 'name']
|
|
335
|
+
|
|
336
|
+
toTranslationTableName('products'); // 'products_translations'
|
|
337
|
+
toTranslationFKName('products'); // 'product_id'
|
|
338
|
+
|
|
339
|
+
singularize('products'); // 'product'
|
|
340
|
+
pluralize('product'); // 'products'
|
|
341
|
+
toPascalCase('user_id'); // 'UserId'
|
|
342
|
+
toCamelCase('user_id'); // 'userId'
|
|
343
|
+
toSnakeCase('userId'); // 'user_id'
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Schema Validation
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
import {
|
|
350
|
+
validateSchema,
|
|
351
|
+
assertValidSchema,
|
|
352
|
+
isValidSchema,
|
|
353
|
+
} from '@promakeai/orm';
|
|
354
|
+
|
|
355
|
+
// Returns array of errors
|
|
356
|
+
const errors = validateSchema(schema);
|
|
357
|
+
// [{ path: 'tables.users.email', message: '...' }]
|
|
358
|
+
|
|
359
|
+
// Throws on invalid schema
|
|
360
|
+
assertValidSchema(schema);
|
|
361
|
+
|
|
362
|
+
// Boolean check
|
|
363
|
+
if (isValidSchema(schema)) {
|
|
364
|
+
// ...
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Schema Merging
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
import { mergeSchemas } from '@promakeai/orm';
|
|
372
|
+
|
|
373
|
+
const schema1 = defineSchema({
|
|
374
|
+
tables: { users: { ... } },
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const schema2 = defineSchema({
|
|
378
|
+
tables: { products: { ... } },
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
const merged = mergeSchemas([schema1, schema2]);
|
|
382
|
+
// { tables: { users: {...}, products: {...} } }
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## IDataAdapter Interface
|
|
386
|
+
|
|
387
|
+
All adapters must implement this interface:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
interface IDataAdapter {
|
|
391
|
+
schema?: SchemaDefinition;
|
|
392
|
+
defaultLang?: string;
|
|
393
|
+
|
|
394
|
+
// Query methods
|
|
395
|
+
list<T>(table: string, options?: QueryOptions): Promise<T[]>;
|
|
396
|
+
get<T>(table: string, id: string | number, options?: QueryOptions): Promise<T | null>;
|
|
397
|
+
count(table: string, options?: QueryOptions): Promise<number>;
|
|
398
|
+
paginate<T>(table: string, page: number, limit: number, options?: QueryOptions): Promise<PaginatedResult<T>>;
|
|
399
|
+
|
|
400
|
+
// Write methods
|
|
401
|
+
create<T>(table: string, data: Record<string, unknown>): Promise<T>;
|
|
402
|
+
update<T>(table: string, id: string | number, data: Record<string, unknown>): Promise<T>;
|
|
403
|
+
delete(table: string, id: string | number): Promise<boolean>;
|
|
404
|
+
|
|
405
|
+
// Batch methods
|
|
406
|
+
createMany<T>(table: string, records: Record<string, unknown>[], options?: { ignore?: boolean }): Promise<{ created: number; ids: (number | bigint)[] }>;
|
|
407
|
+
updateMany(table: string, updates: { id: number | string; data: Record<string, unknown> }[]): Promise<{ updated: number }>;
|
|
408
|
+
deleteMany(table: string, ids: (number | string)[]): Promise<{ deleted: number }>;
|
|
409
|
+
|
|
410
|
+
// Translation methods
|
|
411
|
+
createWithTranslations<T>(table: string, data: Record<string, unknown>, translations?: Record<string, Record<string, unknown>>): Promise<T>;
|
|
412
|
+
upsertTranslation(table: string, id: string | number, lang: string, data: Record<string, unknown>): Promise<void>;
|
|
413
|
+
getTranslations<T>(table: string, id: string | number): Promise<T[]>;
|
|
414
|
+
|
|
415
|
+
// Raw queries
|
|
416
|
+
raw<T>(query: string, params?: unknown[]): Promise<T[]>;
|
|
417
|
+
execute(query: string, params?: unknown[]): Promise<{ changes: number; lastInsertRowid: number | bigint }>;
|
|
418
|
+
|
|
419
|
+
// Transactions
|
|
420
|
+
beginTransaction(): Promise<void>;
|
|
421
|
+
commit(): Promise<void>;
|
|
422
|
+
rollback(): Promise<void>;
|
|
423
|
+
|
|
424
|
+
// Schema
|
|
425
|
+
getTables?(): Promise<string[]>;
|
|
426
|
+
getTableSchema?(table: string): Promise<unknown[]>;
|
|
427
|
+
|
|
428
|
+
// Lifecycle
|
|
429
|
+
connect?(): void | Promise<void>;
|
|
430
|
+
close(): void | Promise<void>;
|
|
431
|
+
}
|
|
133
432
|
```
|
|
134
433
|
|
|
135
|
-
## Types
|
|
434
|
+
## TypeScript Types
|
|
136
435
|
|
|
137
436
|
```typescript
|
|
138
437
|
import type {
|
|
139
|
-
|
|
438
|
+
SchemaDefinition,
|
|
140
439
|
TableDefinition,
|
|
141
440
|
FieldDefinition,
|
|
441
|
+
FieldType,
|
|
442
|
+
FieldReference,
|
|
142
443
|
QueryOptions,
|
|
143
444
|
WhereClause,
|
|
445
|
+
OrderByOption,
|
|
446
|
+
PopulateOption,
|
|
447
|
+
PaginatedResult,
|
|
448
|
+
IDataAdapter,
|
|
144
449
|
} from '@promakeai/orm';
|
|
145
450
|
```
|
|
146
451
|
|
|
147
452
|
## Related Packages
|
|
148
453
|
|
|
149
|
-
- [@promakeai/dbcli](../dbcli) - CLI tool
|
|
150
|
-
- [@promakeai/dbreact](../dbreact) - React
|
|
454
|
+
- [@promakeai/dbcli](../dbcli) - CLI tool for database operations
|
|
455
|
+
- [@promakeai/dbreact](../dbreact) - React hooks and providers
|
|
151
456
|
|
|
152
457
|
## License
|
|
153
458
|
|
|
@@ -38,6 +38,10 @@ export interface IDataAdapter {
|
|
|
38
38
|
* Get single record by ID
|
|
39
39
|
*/
|
|
40
40
|
get<T = unknown>(table: string, id: string | number, options?: QueryOptions): Promise<T | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Find first record matching query (like Mongoose findOne)
|
|
43
|
+
*/
|
|
44
|
+
findOne<T = unknown>(table: string, options?: QueryOptions): Promise<T | null>;
|
|
41
45
|
/**
|
|
42
46
|
* Count records matching condition
|
|
43
47
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -47,4 +47,6 @@ export type { TranslationQueryOptions, TranslationQueryResult, } from "./utils/t
|
|
|
47
47
|
export { resolvePopulate, getPopulatableFields, validatePopulate, } from "./utils/populateResolver";
|
|
48
48
|
export type { PopulateAdapter } from "./utils/populateResolver";
|
|
49
49
|
export { parseJSONSchema } from "./utils/jsonConverter";
|
|
50
|
-
export
|
|
50
|
+
export { isJsonType } from "./types";
|
|
51
|
+
export { deserializeRow, serializeRow } from "./utils/deserializer";
|
|
52
|
+
export type { FieldType, FieldDefinition, FieldReference, FieldBuilderLike, TableDefinition, LanguageConfig, SchemaDefinition, SchemaInput, JSONFieldType, JSONFieldDefinition, JSONTableDefinition, JSONSchemaDefinition, WhereCondition, OrderByOption, PopulateOption, PopulateNested, QueryOptions, PaginatedResult, ORMConfig, } from "./types";
|