@ooneex/database 0.0.1
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/LICENSE +21 -0
- package/README.md +607 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +13 -0
- package/dist/ooneex-database-0.0.1.tgz +0 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ooneex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# @ooneex/database
|
|
2
|
+
|
|
3
|
+
A comprehensive TypeScript/JavaScript database library designed for Bun runtime. This package provides a unified interface for database operations with support for SQLite, PostgreSQL, MySQL, and Redis, along with TypeORM adapters for advanced ORM functionality.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
✅ **Multi-Database Support** - SQLite, PostgreSQL, MySQL, and Redis support
|
|
12
|
+
|
|
13
|
+
✅ **Bun Native** - Built specifically for Bun runtime with Bun.SQL
|
|
14
|
+
|
|
15
|
+
✅ **TypeORM Integration** - Dedicated adapters for PostgreSQL and SQLite
|
|
16
|
+
|
|
17
|
+
✅ **Type-Safe** - Full TypeScript support with proper type definitions
|
|
18
|
+
|
|
19
|
+
✅ **Connection Management** - Robust connection opening, closing, and lifecycle management
|
|
20
|
+
|
|
21
|
+
✅ **Database Operations** - Create, drop, and manage database instances
|
|
22
|
+
|
|
23
|
+
✅ **Error Handling** - Comprehensive error handling with custom exceptions
|
|
24
|
+
|
|
25
|
+
✅ **Environment Support** - Automatic environment variable detection
|
|
26
|
+
|
|
27
|
+
✅ **Zero Configuration** - Works out of the box with sensible defaults
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### Bun
|
|
32
|
+
```bash
|
|
33
|
+
bun add @ooneex/database
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### TypeORM PostgreSQL Adapter
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { TypeormPgDatabaseAdapter } from '@ooneex/database';
|
|
42
|
+
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
|
|
43
|
+
|
|
44
|
+
@Entity()
|
|
45
|
+
class User {
|
|
46
|
+
@PrimaryGeneratedColumn()
|
|
47
|
+
id: number;
|
|
48
|
+
|
|
49
|
+
@Column()
|
|
50
|
+
name: string;
|
|
51
|
+
|
|
52
|
+
@Column()
|
|
53
|
+
email: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const adapter = new TypeormPgDatabaseAdapter({
|
|
57
|
+
url: 'postgresql://user:pass@localhost:5432/mydb',
|
|
58
|
+
synchronize: true,
|
|
59
|
+
entities: [User]
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Open and get repository
|
|
63
|
+
const userRepository = await adapter.open(User);
|
|
64
|
+
|
|
65
|
+
// Create user
|
|
66
|
+
const user = userRepository.create({
|
|
67
|
+
name: 'John Doe',
|
|
68
|
+
email: 'john@example.com'
|
|
69
|
+
});
|
|
70
|
+
await userRepository.save(user);
|
|
71
|
+
|
|
72
|
+
// Find users
|
|
73
|
+
const users = await userRepository.find();
|
|
74
|
+
|
|
75
|
+
// Close connection
|
|
76
|
+
await adapter.close();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### TypeORM SQLite Adapter
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { TypeormSqliteDatabaseAdapter } from '@ooneex/database';
|
|
83
|
+
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
|
|
84
|
+
|
|
85
|
+
@Entity()
|
|
86
|
+
class Product {
|
|
87
|
+
@PrimaryGeneratedColumn()
|
|
88
|
+
id: number;
|
|
89
|
+
|
|
90
|
+
@Column()
|
|
91
|
+
name: string;
|
|
92
|
+
|
|
93
|
+
@Column('decimal')
|
|
94
|
+
price: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const adapter = new TypeormSqliteDatabaseAdapter({
|
|
98
|
+
database: './products.db',
|
|
99
|
+
synchronize: true,
|
|
100
|
+
entities: [Product]
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Open and get repository
|
|
104
|
+
const productRepository = await adapter.open(Product);
|
|
105
|
+
|
|
106
|
+
// Create product
|
|
107
|
+
const product = productRepository.create({
|
|
108
|
+
name: 'Laptop',
|
|
109
|
+
price: 999.99
|
|
110
|
+
});
|
|
111
|
+
await productRepository.save(product);
|
|
112
|
+
|
|
113
|
+
// Close connection
|
|
114
|
+
await adapter.close();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Error Handling
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { Database, DatabaseException } from '@ooneex/database';
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const db = new Database('invalid://connection');
|
|
124
|
+
await db.open();
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (error instanceof DatabaseException) {
|
|
127
|
+
console.error('Database error:', error.message);
|
|
128
|
+
console.error('Error data:', error.data);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Environment Configuration
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Set in your .env file
|
|
137
|
+
DATABASE_URL=sqlite://./myapp.db
|
|
138
|
+
# or
|
|
139
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
|
|
140
|
+
# or
|
|
141
|
+
DATABASE_URL=mysql://user:password@localhost:3306/mydb
|
|
142
|
+
|
|
143
|
+
# For SQLite adapter
|
|
144
|
+
SQLITE_DATABASE_PATH=./myapp.db
|
|
145
|
+
|
|
146
|
+
# For Redis adapter
|
|
147
|
+
REDIS_URL=redis://localhost:6379
|
|
148
|
+
# or
|
|
149
|
+
VALKEY_URL=redis://localhost:6379
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## API Reference
|
|
153
|
+
|
|
154
|
+
### `Database` Class
|
|
155
|
+
|
|
156
|
+
The main database class providing connection management and basic operations.
|
|
157
|
+
|
|
158
|
+
#### Constructor
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
constructor(connectionString?: string | URL, options?: Bun.SQL.Options)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Parameters:**
|
|
165
|
+
- `connectionString` - Database connection string or URL object
|
|
166
|
+
- `options` - Bun.SQL connection options
|
|
167
|
+
|
|
168
|
+
**Example:**
|
|
169
|
+
```typescript
|
|
170
|
+
const db = new Database('sqlite://./app.db', { timeout: 5000 });
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### Methods
|
|
174
|
+
|
|
175
|
+
##### `getClient(): Bun.SQL`
|
|
176
|
+
Returns the underlying Bun.SQL client instance.
|
|
177
|
+
|
|
178
|
+
**Returns:** The Bun.SQL client
|
|
179
|
+
|
|
180
|
+
**Example:**
|
|
181
|
+
```typescript
|
|
182
|
+
const client = db.getClient();
|
|
183
|
+
const result = await client`SELECT * FROM users`;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
##### `open(): Promise<void>`
|
|
187
|
+
Opens the database connection.
|
|
188
|
+
|
|
189
|
+
**Example:**
|
|
190
|
+
```typescript
|
|
191
|
+
await db.open();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
##### `close(): Promise<void>`
|
|
195
|
+
Closes the database connection.
|
|
196
|
+
|
|
197
|
+
**Example:**
|
|
198
|
+
```typescript
|
|
199
|
+
await db.close();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
##### `drop(): Promise<void>`
|
|
203
|
+
Drops the database. **Caution: This is destructive and cannot be undone.**
|
|
204
|
+
|
|
205
|
+
**Example:**
|
|
206
|
+
```typescript
|
|
207
|
+
await db.drop(); // Permanently deletes the database
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### `TypeormPgDatabaseAdapter` Class
|
|
211
|
+
|
|
212
|
+
TypeORM adapter for PostgreSQL databases.
|
|
213
|
+
|
|
214
|
+
#### Constructor
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
constructor(options: Omit<PostgresConnectionOptions, "type">)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Parameters:**
|
|
221
|
+
- `options` - PostgreSQL connection options (without type field)
|
|
222
|
+
|
|
223
|
+
#### Methods
|
|
224
|
+
|
|
225
|
+
##### `getSource(): DataSource`
|
|
226
|
+
Returns the TypeORM DataSource instance.
|
|
227
|
+
|
|
228
|
+
##### `open<Entity>(entity: EntityTarget<Entity>): Promise<Repository<Entity>>`
|
|
229
|
+
Opens connection and returns repository for the specified entity.
|
|
230
|
+
|
|
231
|
+
##### `close(): Promise<void>`
|
|
232
|
+
Closes the database connection.
|
|
233
|
+
|
|
234
|
+
##### `drop(): Promise<void>`
|
|
235
|
+
Drops the database schema.
|
|
236
|
+
|
|
237
|
+
##### `getEntityManager(): EntityManager`
|
|
238
|
+
Returns the TypeORM EntityManager.
|
|
239
|
+
|
|
240
|
+
### `TypeormSqliteDatabaseAdapter` Class
|
|
241
|
+
|
|
242
|
+
TypeORM adapter for SQLite databases.
|
|
243
|
+
|
|
244
|
+
#### Constructor
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
constructor(options: Omit<SqliteConnectionOptions, "type">)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Parameters:**
|
|
251
|
+
- `options` - SQLite connection options (without type field)
|
|
252
|
+
|
|
253
|
+
#### Methods
|
|
254
|
+
|
|
255
|
+
Same methods as `TypeormPgDatabaseAdapter` but optimized for SQLite.
|
|
256
|
+
|
|
257
|
+
### `RedisDatabaseAdapter` Class
|
|
258
|
+
|
|
259
|
+
Redis adapter using Bun's native Redis client.
|
|
260
|
+
|
|
261
|
+
#### Constructor
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
constructor(options: RedisConnectionOptions = {})
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Parameters:**
|
|
268
|
+
- `options` - Redis connection configuration
|
|
269
|
+
|
|
270
|
+
**Options:**
|
|
271
|
+
- `url` - Redis connection URL (defaults to environment variables or localhost)
|
|
272
|
+
- `connectionTimeout` - Connection timeout in milliseconds (default: 10000)
|
|
273
|
+
- `idleTimeout` - Idle timeout in milliseconds (default: 0)
|
|
274
|
+
- `autoReconnect` - Whether to automatically reconnect (default: true)
|
|
275
|
+
- `maxRetries` - Maximum reconnection attempts (default: 10)
|
|
276
|
+
- `enableOfflineQueue` - Queue commands when disconnected (default: true)
|
|
277
|
+
- `enableAutoPipelining` - Automatically pipeline commands (default: true)
|
|
278
|
+
- `tls` - TLS configuration (default: false)
|
|
279
|
+
|
|
280
|
+
#### Methods
|
|
281
|
+
|
|
282
|
+
##### `getClient(): RedisClient`
|
|
283
|
+
Returns the underlying Bun Redis client instance.
|
|
284
|
+
|
|
285
|
+
##### `open(): Promise<void>`
|
|
286
|
+
Opens the Redis connection.
|
|
287
|
+
|
|
288
|
+
##### `close(): Promise<void>`
|
|
289
|
+
Closes the Redis connection.
|
|
290
|
+
|
|
291
|
+
##### `drop(): Promise<void>`
|
|
292
|
+
Flushes the current Redis database (FLUSHDB).
|
|
293
|
+
|
|
294
|
+
##### `ping(): Promise<string>`
|
|
295
|
+
Pings the Redis server.
|
|
296
|
+
|
|
297
|
+
##### `info(section?: string): Promise<string>`
|
|
298
|
+
Gets Redis server information.
|
|
299
|
+
|
|
300
|
+
##### `isConnected(): boolean`
|
|
301
|
+
Returns connection status.
|
|
302
|
+
|
|
303
|
+
##### `getBufferedAmount(): number`
|
|
304
|
+
Returns buffered data amount in bytes.
|
|
305
|
+
|
|
306
|
+
### `DatabaseException` Class
|
|
307
|
+
|
|
308
|
+
Custom exception class for database-related errors.
|
|
309
|
+
|
|
310
|
+
#### Constructor
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
constructor(message: string, data?: T)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Parameters:**
|
|
317
|
+
- `message` - Error message
|
|
318
|
+
- `data` - Additional error data
|
|
319
|
+
|
|
320
|
+
### Interfaces
|
|
321
|
+
|
|
322
|
+
#### `IDatabase`
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
interface IDatabase {
|
|
326
|
+
open(): Promise<void>;
|
|
327
|
+
close(): Promise<void>;
|
|
328
|
+
drop(): Promise<void>;
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### `ITypeormDatabaseAdapter`
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
interface ITypeormDatabaseAdapter {
|
|
336
|
+
open(entity: any): Promise<any>;
|
|
337
|
+
close(): Promise<void>;
|
|
338
|
+
drop(): Promise<void>;
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Supported Database URLs
|
|
343
|
+
|
|
344
|
+
### SQLite
|
|
345
|
+
```typescript
|
|
346
|
+
// File-based database
|
|
347
|
+
'sqlite://./database.db'
|
|
348
|
+
'sqlite:database.db'
|
|
349
|
+
'./database.db'
|
|
350
|
+
|
|
351
|
+
// In-memory database
|
|
352
|
+
'sqlite://:memory:'
|
|
353
|
+
':memory:'
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### PostgreSQL
|
|
357
|
+
```typescript
|
|
358
|
+
'postgresql://user:password@localhost:5432/database'
|
|
359
|
+
'postgres://user:password@localhost:5432/database'
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### MySQL
|
|
363
|
+
```typescript
|
|
364
|
+
'mysql://user:password@localhost:3306/database'
|
|
365
|
+
'mysql2://user:password@localhost:3306/database'
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Redis
|
|
369
|
+
```typescript
|
|
370
|
+
// Standard Redis URL
|
|
371
|
+
'redis://localhost:6379'
|
|
372
|
+
|
|
373
|
+
// With authentication
|
|
374
|
+
'redis://username:password@localhost:6379'
|
|
375
|
+
|
|
376
|
+
// With database number
|
|
377
|
+
'redis://localhost:6379/0'
|
|
378
|
+
|
|
379
|
+
// TLS connections
|
|
380
|
+
'rediss://localhost:6379'
|
|
381
|
+
'redis+tls://localhost:6379'
|
|
382
|
+
|
|
383
|
+
// Unix socket connections
|
|
384
|
+
'redis+unix:///path/to/socket'
|
|
385
|
+
'redis+tls+unix:///path/to/socket'
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Best Practices
|
|
389
|
+
|
|
390
|
+
### Connection Management
|
|
391
|
+
- Always call `close()` when done with database operations
|
|
392
|
+
- Use try-catch blocks for proper error handling
|
|
393
|
+
- Consider connection pooling for high-traffic applications
|
|
394
|
+
|
|
395
|
+
### Redis Adapter
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import { RedisDatabaseAdapter } from '@ooneex/database';
|
|
399
|
+
|
|
400
|
+
const adapter = new RedisDatabaseAdapter({
|
|
401
|
+
url: 'redis://localhost:6379',
|
|
402
|
+
connectionTimeout: 10000,
|
|
403
|
+
autoReconnect: true,
|
|
404
|
+
maxRetries: 10
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Open connection
|
|
408
|
+
await adapter.open();
|
|
409
|
+
|
|
410
|
+
// Get Redis client for operations
|
|
411
|
+
const client = adapter.getClient();
|
|
412
|
+
|
|
413
|
+
// Basic operations
|
|
414
|
+
await client.set('user:1', 'Alice');
|
|
415
|
+
const user = await client.get('user:1');
|
|
416
|
+
|
|
417
|
+
// Hash operations
|
|
418
|
+
await client.hmset('user:2', ['name', 'Bob', 'email', 'bob@example.com']);
|
|
419
|
+
const userFields = await client.hmget('user:2', ['name', 'email']);
|
|
420
|
+
|
|
421
|
+
// Set operations
|
|
422
|
+
await client.sadd('tags', 'redis', 'database', 'cache');
|
|
423
|
+
const tags = await client.smembers('tags');
|
|
424
|
+
|
|
425
|
+
// Utility methods
|
|
426
|
+
const pingResult = await adapter.ping();
|
|
427
|
+
const serverInfo = await adapter.info('server');
|
|
428
|
+
|
|
429
|
+
// Close connection
|
|
430
|
+
await adapter.close();
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Error Handling
|
|
434
|
+
- Catch `DatabaseException` specifically for database errors
|
|
435
|
+
- Log error details for debugging
|
|
436
|
+
- Implement retry logic for transient failures
|
|
437
|
+
|
|
438
|
+
### Security
|
|
439
|
+
- Never hardcode database credentials
|
|
440
|
+
- Use environment variables for sensitive information
|
|
441
|
+
- Validate input data before database operations
|
|
442
|
+
|
|
443
|
+
### Performance
|
|
444
|
+
- Use prepared statements when possible
|
|
445
|
+
- Implement proper indexing strategies
|
|
446
|
+
- Monitor query performance in production
|
|
447
|
+
|
|
448
|
+
## TypeORM Integration
|
|
449
|
+
|
|
450
|
+
This package provides specialized adapters for TypeORM, allowing you to leverage the full power of TypeORM while maintaining the simplicity of the Ooneex database interface.
|
|
451
|
+
|
|
452
|
+
### PostgreSQL with TypeORM
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
import { TypeormPgDatabaseAdapter } from '@ooneex/database';
|
|
456
|
+
|
|
457
|
+
const adapter = new TypeormPgDatabaseAdapter({
|
|
458
|
+
url: process.env.DATABASE_URL,
|
|
459
|
+
synchronize: false, // Set to true only in development
|
|
460
|
+
entities: [User, Product, Order],
|
|
461
|
+
migrations: ['./migrations/**/*.ts'],
|
|
462
|
+
extra: {
|
|
463
|
+
max: 20, // Maximum number of connections
|
|
464
|
+
idleTimeoutMillis: 30000
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### SQLite with TypeORM
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { TypeormSqliteDatabaseAdapter } from '@ooneex/database';
|
|
473
|
+
|
|
474
|
+
const adapter = new TypeormSqliteDatabaseAdapter({
|
|
475
|
+
database: './myapp.db',
|
|
476
|
+
synchronize: true,
|
|
477
|
+
entities: [User, Product],
|
|
478
|
+
enableWAL: true, // Write-Ahead Logging for better performance
|
|
479
|
+
busyTimeout: 30000
|
|
480
|
+
});
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## Redis Integration
|
|
484
|
+
|
|
485
|
+
This package provides a native Redis adapter built specifically for Bun's Redis client, offering high-performance Redis operations with full TypeScript support.
|
|
486
|
+
|
|
487
|
+
### Basic Redis Usage
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
import { RedisDatabaseAdapter } from '@ooneex/database';
|
|
491
|
+
|
|
492
|
+
const adapter = new RedisDatabaseAdapter({
|
|
493
|
+
url: process.env.REDIS_URL,
|
|
494
|
+
connectionTimeout: 5000,
|
|
495
|
+
autoReconnect: true
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
await adapter.open();
|
|
499
|
+
const client = adapter.getClient();
|
|
500
|
+
|
|
501
|
+
// String operations
|
|
502
|
+
await client.set('key', 'value');
|
|
503
|
+
const value = await client.get('key');
|
|
504
|
+
|
|
505
|
+
// Numeric operations
|
|
506
|
+
await client.incr('counter');
|
|
507
|
+
await client.decr('counter');
|
|
508
|
+
|
|
509
|
+
// Hash operations
|
|
510
|
+
await client.hmset('user:1', ['name', 'Alice', 'email', 'alice@example.com']);
|
|
511
|
+
const userData = await client.hmget('user:1', ['name', 'email']);
|
|
512
|
+
|
|
513
|
+
// Set operations
|
|
514
|
+
await client.sadd('tags', 'redis', 'cache');
|
|
515
|
+
const allTags = await client.smembers('tags');
|
|
516
|
+
|
|
517
|
+
await adapter.close();
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### Redis Pub/Sub
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
const publisher = new RedisDatabaseAdapter();
|
|
524
|
+
const subscriber = new RedisDatabaseAdapter();
|
|
525
|
+
|
|
526
|
+
await publisher.open();
|
|
527
|
+
await subscriber.open();
|
|
528
|
+
|
|
529
|
+
// Set up subscription
|
|
530
|
+
const subClient = subscriber.getClient();
|
|
531
|
+
await subClient.subscribe('notifications', (message, channel) => {
|
|
532
|
+
console.log(`Received: ${message} on ${channel}`);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
// Publish message
|
|
536
|
+
const pubClient = publisher.getClient();
|
|
537
|
+
await pubClient.publish('notifications', 'Hello subscribers!');
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Redis Caching Pattern
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
async function getUserWithCache(userId: number) {
|
|
544
|
+
const cacheKey = `user:${userId}`;
|
|
545
|
+
|
|
546
|
+
// Try cache first
|
|
547
|
+
const cached = await client.get(cacheKey);
|
|
548
|
+
if (cached) {
|
|
549
|
+
return JSON.parse(cached);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Fetch from database
|
|
553
|
+
const user = await database.getUser(userId);
|
|
554
|
+
|
|
555
|
+
// Cache with expiration
|
|
556
|
+
await client.set(cacheKey, JSON.stringify(user));
|
|
557
|
+
await client.expire(cacheKey, 3600); // 1 hour
|
|
558
|
+
|
|
559
|
+
return user;
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Redis Rate Limiting
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
async function rateLimit(ip: string, limit: number = 100, windowSecs: number = 3600) {
|
|
567
|
+
const key = `ratelimit:${ip}`;
|
|
568
|
+
|
|
569
|
+
const count = await client.incr(key);
|
|
570
|
+
|
|
571
|
+
if (count === 1) {
|
|
572
|
+
await client.expire(key, windowSecs);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
return {
|
|
576
|
+
allowed: count <= limit,
|
|
577
|
+
remaining: Math.max(0, limit - count)
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
## License
|
|
583
|
+
|
|
584
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
585
|
+
|
|
586
|
+
## Contributing
|
|
587
|
+
|
|
588
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
589
|
+
|
|
590
|
+
### Development Setup
|
|
591
|
+
|
|
592
|
+
1. Clone the repository
|
|
593
|
+
2. Install dependencies: `bun install`
|
|
594
|
+
3. Run tests: `bun run test`
|
|
595
|
+
4. Build the project: `bun run build`
|
|
596
|
+
|
|
597
|
+
### Guidelines
|
|
598
|
+
|
|
599
|
+
- Write tests for new features
|
|
600
|
+
- Follow the existing code style
|
|
601
|
+
- Update documentation for API changes
|
|
602
|
+
- Ensure all tests pass before submitting PR
|
|
603
|
+
- Test with different database types (SQLite, PostgreSQL, MySQL)
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
Made with ❤️ by the Ooneex team
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Exception } from "@ooneex/exception";
|
|
2
|
+
declare class DatabaseException extends Exception {
|
|
3
|
+
constructor(message: string, data?: Record<string, unknown>);
|
|
4
|
+
}
|
|
5
|
+
import { RedisClient as RedisClient2 } from "bun";
|
|
6
|
+
import { RedisClient } from "bun";
|
|
7
|
+
import { EntityTarget, ObjectLiteral, Repository } from "typeorm";
|
|
8
|
+
type DatabaseClassType = new (...args: any[]) => IDatabase | IRedisDatabaseAdapter | ITypeormDatabaseAdapter;
|
|
9
|
+
type RedisConnectionOptionsType = {
|
|
10
|
+
url?: string;
|
|
11
|
+
connectionTimeout?: number;
|
|
12
|
+
idleTimeout?: number;
|
|
13
|
+
autoReconnect?: boolean;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
enableOfflineQueue?: boolean;
|
|
16
|
+
enableAutoPipelining?: boolean;
|
|
17
|
+
tls?: boolean | {
|
|
18
|
+
rejectUnauthorized?: boolean;
|
|
19
|
+
ca?: string;
|
|
20
|
+
cert?: string;
|
|
21
|
+
key?: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
interface IDatabase {
|
|
25
|
+
open: () => Promise<void>;
|
|
26
|
+
close: () => Promise<void>;
|
|
27
|
+
drop: () => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
interface IRedisDatabaseAdapter {
|
|
30
|
+
open: () => Promise<RedisClient>;
|
|
31
|
+
close: () => Promise<void>;
|
|
32
|
+
drop: () => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
interface ITypeormDatabaseAdapter {
|
|
35
|
+
open: <Entity extends ObjectLiteral>(entity: EntityTarget<Entity>) => Promise<Repository<Entity>>;
|
|
36
|
+
close: () => Promise<void>;
|
|
37
|
+
drop: () => Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
declare class RedisDatabaseAdapter implements IRedisDatabaseAdapter {
|
|
40
|
+
private readonly options;
|
|
41
|
+
private client;
|
|
42
|
+
private connectionUrl;
|
|
43
|
+
constructor(options?: RedisConnectionOptionsType);
|
|
44
|
+
getClient(): RedisClient2;
|
|
45
|
+
open(): Promise<RedisClient2>;
|
|
46
|
+
close(): Promise<void>;
|
|
47
|
+
drop(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
import { DataSource, EntityManager, EntityTarget as EntityTarget2, ObjectLiteral as ObjectLiteral2, Repository as Repository2 } from "typeorm";
|
|
50
|
+
import { PostgresConnectionOptions } from "typeorm/driver/postgres/PostgresConnectionOptions";
|
|
51
|
+
declare class TypeormPgDatabaseAdapter implements ITypeormDatabaseAdapter {
|
|
52
|
+
private source;
|
|
53
|
+
constructor(options: Omit<PostgresConnectionOptions, "type">);
|
|
54
|
+
getSource(): DataSource;
|
|
55
|
+
open<Entity extends ObjectLiteral2>(entity: EntityTarget2<Entity>): Promise<Repository2<Entity>>;
|
|
56
|
+
close(): Promise<void>;
|
|
57
|
+
drop(): Promise<void>;
|
|
58
|
+
getEntityManager(): EntityManager;
|
|
59
|
+
}
|
|
60
|
+
import { DataSource as DataSource2, EntityManager as EntityManager2, EntityTarget as EntityTarget3, ObjectLiteral as ObjectLiteral3, Repository as Repository3 } from "typeorm";
|
|
61
|
+
import { SqliteConnectionOptions } from "typeorm/driver/sqlite/SqliteConnectionOptions";
|
|
62
|
+
declare class TypeormSqliteDatabaseAdapter implements ITypeormDatabaseAdapter {
|
|
63
|
+
private source;
|
|
64
|
+
constructor(options: Omit<SqliteConnectionOptions, "type">);
|
|
65
|
+
getSource(): DataSource2;
|
|
66
|
+
open<Entity extends ObjectLiteral3>(entity: EntityTarget3<Entity>): Promise<Repository3<Entity>>;
|
|
67
|
+
close(): Promise<void>;
|
|
68
|
+
drop(): Promise<void>;
|
|
69
|
+
getEntityManager(): EntityManager2;
|
|
70
|
+
}
|
|
71
|
+
export { TypeormSqliteDatabaseAdapter, TypeormPgDatabaseAdapter, RedisDatabaseAdapter, RedisConnectionOptionsType, ITypeormDatabaseAdapter, IRedisDatabaseAdapter, IDatabase, DatabaseException, DatabaseClassType };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Exception as r}from"@ooneex/exception";import{HttpStatus as a}from"@ooneex/http-status";class i extends r{constructor(t,e={}){super(t,{status:a.Code.InternalServerError,data:e});this.name="DatabaseException"}}var{RedisClient:o}=globalThis.Bun;class s{options;client;connectionUrl;constructor(t={}){this.options=t;if(this.connectionUrl=t.url||Bun.env.DATABASE_REDIS_URL||"",!this.connectionUrl)throw new i("No Redis connection URL provided. The 'url' option must be specified or set the following environment variable: DATABASE_REDIS_URL.",{...t,connectionUrl:this.connectionUrl});this.client=new o(this.connectionUrl,{connectionTimeout:t.connectionTimeout||1e4,idleTimeout:t.idleTimeout||0,autoReconnect:t.autoReconnect??!0,maxRetries:t.maxRetries||10,enableOfflineQueue:t.enableOfflineQueue??!0,enableAutoPipelining:t.enableAutoPipelining??!0,...t.tls!==void 0&&{tls:t.tls}})}getClient(){return this.client}async open(){try{if(!this.client.connected)await this.client.connect();return this.client}catch(t){throw new i(`Failed to open Redis connection: ${t instanceof Error?t.message:String(t)}`,{connectionUrl:this.connectionUrl,options:this.options,error:t})}}async close(){try{if(this.client.connected)this.client.close()}catch(t){throw new i(`Failed to close Redis connection: ${t instanceof Error?t.message:String(t)}`,{connectionUrl:this.connectionUrl,error:t})}}async drop(){try{if(!this.client.connected)await this.open();await this.client.send("FLUSHDB",[])}catch(t){throw new i(`Failed to drop Redis database: ${t instanceof Error?t.message:String(t)}`,{connectionUrl:this.connectionUrl,error:t})}}}import{DataSource as n}from"typeorm";class c{source;constructor(t){let e=(t.url||Bun.env.DATABASE_URL||"").trim();if(!e)throw new i("No database URL provided. Please set DATABASE_URL environment variable or provide a url in the options.",{...t,url:e});this.source=new n({synchronize:!1,entities:[],extra:{max:10},...t,url:e,type:"postgres"})}getSource(){return this.source}async open(t){let e=this.getSource();if(!e.isInitialized)await e.initialize();return e.getRepository(t)}async close(){let t=this.getSource();if(t.isInitialized)await t.destroy()}async drop(){let t=this.getSource();if(t.isInitialized)await t.dropDatabase()}getEntityManager(){return this.getSource().manager}}import{DataSource as p}from"typeorm";class y{source;constructor(t){let e=t.database||Bun.env.SQLITE_DATABASE_PATH||"";if(!e)throw new i("No database path provided. The 'database' option must be specified with a valid file path or ':memory:' for in-memory database. Alternatively, set the SQLITE_DATABASE_PATH environment variable.",{...t,database:e});this.source=new p({synchronize:!1,entities:[],enableWAL:!0,busyErrorRetry:2000,busyTimeout:30000,...t,database:e,type:"sqlite"})}getSource(){return this.source}async open(t){let e=this.getSource();if(!e.isInitialized)await e.initialize();return e.getRepository(t)}async close(){let t=this.getSource();if(t.isInitialized)await t.destroy()}async drop(){let t=this.getSource();if(t.isInitialized)await t.dropDatabase()}getEntityManager(){return this.getSource().manager}}export{y as TypeormSqliteDatabaseAdapter,c as TypeormPgDatabaseAdapter,s as RedisDatabaseAdapter,i as DatabaseException};
|
|
3
|
+
|
|
4
|
+
//# debugId=6EB87EF735D078EC64756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/DatabaseException.ts", "src/RedisDatabaseAdapter.ts", "src/TypeormPgDatabaseAdapter.ts", "src/TypeormSqliteDatabaseAdapter.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class DatabaseException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"DatabaseException\";\n }\n}\n",
|
|
6
|
+
"import { RedisClient } from \"bun\";\nimport { DatabaseException } from \"./DatabaseException\";\nimport type { IRedisDatabaseAdapter, RedisConnectionOptionsType } from \"./types\";\n\nexport class RedisDatabaseAdapter implements IRedisDatabaseAdapter {\n private client: RedisClient;\n private connectionUrl: string;\n\n constructor(private readonly options: RedisConnectionOptionsType = {}) {\n this.connectionUrl = options.url || Bun.env.DATABASE_REDIS_URL || \"\";\n\n if (!this.connectionUrl) {\n throw new DatabaseException(\n \"No Redis connection URL provided. The 'url' option must be specified or set the following environment variable: DATABASE_REDIS_URL.\",\n {\n ...options,\n connectionUrl: this.connectionUrl,\n },\n );\n }\n\n // Create Redis client with options\n this.client = new RedisClient(this.connectionUrl, {\n connectionTimeout: options.connectionTimeout || 10_000,\n idleTimeout: options.idleTimeout || 0,\n autoReconnect: options.autoReconnect ?? true,\n maxRetries: options.maxRetries || 10,\n enableOfflineQueue: options.enableOfflineQueue ?? true,\n enableAutoPipelining: options.enableAutoPipelining ?? true,\n ...(options.tls !== undefined && { tls: options.tls }),\n });\n }\n\n public getClient(): RedisClient {\n return this.client;\n }\n\n public async open(): Promise<RedisClient> {\n try {\n if (!this.client.connected) {\n await this.client.connect();\n }\n\n return this.client;\n } catch (error) {\n throw new DatabaseException(\n `Failed to open Redis connection: ${error instanceof Error ? error.message : String(error)}`,\n {\n connectionUrl: this.connectionUrl,\n options: this.options,\n error,\n },\n );\n }\n }\n\n public async close(): Promise<void> {\n try {\n if (this.client.connected) {\n this.client.close();\n }\n } catch (error) {\n throw new DatabaseException(\n `Failed to close Redis connection: ${error instanceof Error ? error.message : String(error)}`,\n {\n connectionUrl: this.connectionUrl,\n error,\n },\n );\n }\n }\n\n public async drop(): Promise<void> {\n try {\n if (!this.client.connected) {\n await this.open();\n }\n\n // Use FLUSHDB to clear the current database\n await this.client.send(\"FLUSHDB\", []);\n } catch (error) {\n throw new DatabaseException(\n `Failed to drop Redis database: ${error instanceof Error ? error.message : String(error)}`,\n {\n connectionUrl: this.connectionUrl,\n error,\n },\n );\n }\n }\n}\n",
|
|
7
|
+
"import { DataSource, type EntityManager, type EntityTarget, type ObjectLiteral, type Repository } from \"typeorm\";\nimport type { PostgresConnectionOptions } from \"typeorm/driver/postgres/PostgresConnectionOptions.js\";\nimport { DatabaseException } from \"./DatabaseException\";\nimport type { ITypeormDatabaseAdapter } from \"./types\";\n\nexport class TypeormPgDatabaseAdapter implements ITypeormDatabaseAdapter {\n private source: DataSource;\n\n constructor(options: Omit<PostgresConnectionOptions, \"type\">) {\n const url = (options.url || Bun.env.DATABASE_URL || \"\").trim();\n\n if (!url) {\n throw new DatabaseException(\n \"No database URL provided. Please set DATABASE_URL environment variable or provide a url in the options.\",\n {\n ...options,\n url,\n },\n );\n }\n\n this.source = new DataSource({\n synchronize: false,\n entities: [],\n extra: {\n max: 10,\n // idleTimeoutMillis: 30000,\n },\n ...options,\n url,\n type: \"postgres\",\n });\n }\n\n public getSource(): DataSource {\n return this.source;\n }\n\n public async open<Entity extends ObjectLiteral>(entity: EntityTarget<Entity>): Promise<Repository<Entity>> {\n const source = this.getSource();\n\n if (!source.isInitialized) {\n await source.initialize();\n }\n\n return source.getRepository(entity);\n }\n\n public async close(): Promise<void> {\n const source = this.getSource();\n if (source.isInitialized) {\n await source.destroy();\n }\n }\n\n public async drop(): Promise<void> {\n const source = this.getSource();\n if (source.isInitialized) {\n await source.dropDatabase();\n }\n }\n\n public getEntityManager(): EntityManager {\n return this.getSource().manager;\n }\n}\n",
|
|
8
|
+
"import { DataSource, type EntityManager, type EntityTarget, type ObjectLiteral, type Repository } from \"typeorm\";\nimport type { SqliteConnectionOptions } from \"typeorm/driver/sqlite/SqliteConnectionOptions.js\";\nimport { DatabaseException } from \"./DatabaseException\";\nimport type { ITypeormDatabaseAdapter } from \"./types\";\n\nexport class TypeormSqliteDatabaseAdapter implements ITypeormDatabaseAdapter {\n private source: DataSource;\n\n constructor(options: Omit<SqliteConnectionOptions, \"type\">) {\n const database = options.database || Bun.env.SQLITE_DATABASE_PATH || \"\";\n\n if (!database) {\n throw new DatabaseException(\n \"No database path provided. The 'database' option must be specified with a valid file path or ':memory:' for in-memory database. Alternatively, set the SQLITE_DATABASE_PATH environment variable.\",\n {\n ...options,\n database,\n },\n );\n }\n\n this.source = new DataSource({\n synchronize: false,\n entities: [],\n enableWAL: true,\n busyErrorRetry: 2000,\n busyTimeout: 30_000,\n ...options,\n database,\n type: \"sqlite\",\n });\n }\n\n public getSource(): DataSource {\n return this.source;\n }\n\n public async open<Entity extends ObjectLiteral>(entity: EntityTarget<Entity>): Promise<Repository<Entity>> {\n const source = this.getSource();\n\n if (!source.isInitialized) {\n await source.initialize();\n }\n\n return source.getRepository(entity);\n }\n\n public async close(): Promise<void> {\n const source = this.getSource();\n if (source.isInitialized) {\n await source.destroy();\n }\n }\n\n public async drop(): Promise<void> {\n const source = this.getSource();\n if (source.isInitialized) {\n await source.dropDatabase();\n }\n }\n\n public getEntityManager(): EntityManager {\n return this.getSource().manager;\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": ";AAAA,oBAAS,0BACT,qBAAS,4BAEF,MAAM,UAA0B,CAAU,CAC/C,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,oBACxB,MACF,CAAC,EACD,KAAK,KAAO,oBAEhB,CCXA,kCAIO,MAAM,CAAsD,CAIpC,QAHrB,OACA,cAER,WAAW,CAAkB,EAAsC,CAAC,EAAG,CAA1C,eAG3B,GAFA,KAAK,cAAgB,EAAQ,KAAO,IAAI,IAAI,oBAAsB,GAE9D,CAAC,KAAK,cACR,MAAM,IAAI,EACR,sIACA,IACK,EACH,cAAe,KAAK,aACtB,CACF,EAIF,KAAK,OAAS,IAAI,EAAY,KAAK,cAAe,CAChD,kBAAmB,EAAQ,mBAAqB,IAChD,YAAa,EAAQ,aAAe,EACpC,cAAe,EAAQ,eAAiB,GACxC,WAAY,EAAQ,YAAc,GAClC,mBAAoB,EAAQ,oBAAsB,GAClD,qBAAsB,EAAQ,sBAAwB,MAClD,EAAQ,MAAQ,QAAa,CAAE,IAAK,EAAQ,GAAI,CACtD,CAAC,EAGI,SAAS,EAAgB,CAC9B,OAAO,KAAK,YAGD,KAAI,EAAyB,CACxC,GAAI,CACF,GAAI,CAAC,KAAK,OAAO,UACf,MAAM,KAAK,OAAO,QAAQ,EAG5B,OAAO,KAAK,OACZ,MAAO,EAAO,CACd,MAAM,IAAI,EACR,oCAAoC,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,IACzF,CACE,cAAe,KAAK,cACpB,QAAS,KAAK,QACd,OACF,CACF,QAIS,MAAK,EAAkB,CAClC,GAAI,CACF,GAAI,KAAK,OAAO,UACd,KAAK,OAAO,MAAM,EAEpB,MAAO,EAAO,CACd,MAAM,IAAI,EACR,qCAAqC,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,IAC1F,CACE,cAAe,KAAK,cACpB,OACF,CACF,QAIS,KAAI,EAAkB,CACjC,GAAI,CACF,GAAI,CAAC,KAAK,OAAO,UACf,MAAM,KAAK,KAAK,EAIlB,MAAM,KAAK,OAAO,KAAK,UAAW,CAAC,CAAC,EACpC,MAAO,EAAO,CACd,MAAM,IAAI,EACR,kCAAkC,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,IACvF,CACE,cAAe,KAAK,cACpB,OACF,CACF,GAGN,CC1FA,qBAAS,gBAKF,MAAM,CAA4D,CAC/D,OAER,WAAW,CAAC,EAAkD,CAC5D,IAAM,GAAO,EAAQ,KAAO,IAAI,IAAI,cAAgB,IAAI,KAAK,EAE7D,GAAI,CAAC,EACH,MAAM,IAAI,EACR,0GACA,IACK,EACH,KACF,CACF,EAGF,KAAK,OAAS,IAAI,EAAW,CAC3B,YAAa,GACb,SAAU,CAAC,EACX,MAAO,CACL,IAAK,EAEP,KACG,EACH,MACA,KAAM,UACR,CAAC,EAGI,SAAS,EAAe,CAC7B,OAAO,KAAK,YAGD,KAAkC,CAAC,EAA2D,CACzG,IAAM,EAAS,KAAK,UAAU,EAE9B,GAAI,CAAC,EAAO,cACV,MAAM,EAAO,WAAW,EAG1B,OAAO,EAAO,cAAc,CAAM,OAGvB,MAAK,EAAkB,CAClC,IAAM,EAAS,KAAK,UAAU,EAC9B,GAAI,EAAO,cACT,MAAM,EAAO,QAAQ,OAIZ,KAAI,EAAkB,CACjC,IAAM,EAAS,KAAK,UAAU,EAC9B,GAAI,EAAO,cACT,MAAM,EAAO,aAAa,EAIvB,gBAAgB,EAAkB,CACvC,OAAO,KAAK,UAAU,EAAE,QAE5B,CCjEA,qBAAS,gBAKF,MAAM,CAAgE,CACnE,OAER,WAAW,CAAC,EAAgD,CAC1D,IAAM,EAAW,EAAQ,UAAY,IAAI,IAAI,sBAAwB,GAErE,GAAI,CAAC,EACH,MAAM,IAAI,EACR,oMACA,IACK,EACH,UACF,CACF,EAGF,KAAK,OAAS,IAAI,EAAW,CAC3B,YAAa,GACb,SAAU,CAAC,EACX,UAAW,GACX,eAAgB,KAChB,YAAa,SACV,EACH,WACA,KAAM,QACR,CAAC,EAGI,SAAS,EAAe,CAC7B,OAAO,KAAK,YAGD,KAAkC,CAAC,EAA2D,CACzG,IAAM,EAAS,KAAK,UAAU,EAE9B,GAAI,CAAC,EAAO,cACV,MAAM,EAAO,WAAW,EAG1B,OAAO,EAAO,cAAc,CAAM,OAGvB,MAAK,EAAkB,CAClC,IAAM,EAAS,KAAK,UAAU,EAC9B,GAAI,EAAO,cACT,MAAM,EAAO,QAAQ,OAIZ,KAAI,EAAkB,CACjC,IAAM,EAAS,KAAK,UAAU,EAC9B,GAAI,EAAO,cACT,MAAM,EAAO,aAAa,EAIvB,gBAAgB,EAAkB,CACvC,OAAO,KAAK,UAAU,EAAE,QAE5B",
|
|
11
|
+
"debugId": "6EB87EF735D078EC64756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ooneex/database",
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"LICENSE",
|
|
9
|
+
"README.md",
|
|
10
|
+
"package.json"
|
|
11
|
+
],
|
|
12
|
+
"module": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"test": "bun test tests",
|
|
26
|
+
"build": "bunup",
|
|
27
|
+
"lint": "tsgo --noEmit && bunx biome lint",
|
|
28
|
+
"publish:prod": "bun publish --tolerate-republish --access public",
|
|
29
|
+
"publish:pack": "bun pm pack --destination ./dist",
|
|
30
|
+
"publish:dry": "bun publish --dry-run"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@ooneex/exception": "0.0.1",
|
|
34
|
+
"@ooneex/http-status": "0.0.1",
|
|
35
|
+
"typeorm": "^0.3.27"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {},
|
|
38
|
+
"devDependencies": {}
|
|
39
|
+
}
|