@ooneex/repository 0.0.1 → 0.0.4

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 CHANGED
@@ -1 +1,664 @@
1
1
  # @ooneex/repository
2
+
3
+ A base repository decorator and interface for data access layer abstraction in TypeScript applications. This package provides the foundation for creating injectable repository classes with dependency injection support, standardized CRUD operations, and paginated query results.
4
+
5
+ ![Browser](https://img.shields.io/badge/Browser-Compatible-green?style=flat-square&logo=googlechrome)
6
+ ![Bun](https://img.shields.io/badge/Bun-Compatible-orange?style=flat-square&logo=bun)
7
+ ![Deno](https://img.shields.io/badge/Deno-Compatible-blue?style=flat-square&logo=deno)
8
+ ![Node.js](https://img.shields.io/badge/Node.js-Compatible-green?style=flat-square&logo=node.js)
9
+ ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript)
10
+ ![MIT License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)
11
+
12
+ ## Features
13
+
14
+ ✅ **Repository Decorator** - Register repositories with the DI container using decorators
15
+
16
+ ✅ **Interface Contract** - Standard interface for repository implementations
17
+
18
+ ✅ **Paginated Results** - Built-in support for paginated query results
19
+
20
+ ✅ **Scope Control** - Configure singleton, transient, or request-scoped repositories
21
+
22
+ ✅ **Type-Safe** - Full TypeScript support with generic entity and criteria types
23
+
24
+ ✅ **Container Integration** - Seamless integration with @ooneex/container
25
+
26
+ ✅ **Search Support** - Built-in query string parameter for search functionality
27
+
28
+ ## Installation
29
+
30
+ ### Bun
31
+ ```bash
32
+ bun add @ooneex/repository
33
+ ```
34
+
35
+ ### pnpm
36
+ ```bash
37
+ pnpm add @ooneex/repository
38
+ ```
39
+
40
+ ### Yarn
41
+ ```bash
42
+ yarn add @ooneex/repository
43
+ ```
44
+
45
+ ### npm
46
+ ```bash
47
+ npm install @ooneex/repository
48
+ ```
49
+
50
+ ## Usage
51
+
52
+ ### Basic Repository
53
+
54
+ ```typescript
55
+ import { decorator, type IRepository } from '@ooneex/repository';
56
+ import type { FilterResultType } from '@ooneex/types';
57
+
58
+ interface User {
59
+ id: string;
60
+ email: string;
61
+ name: string;
62
+ }
63
+
64
+ interface UserCriteria {
65
+ email?: string;
66
+ name?: string;
67
+ isActive?: boolean;
68
+ }
69
+
70
+ @decorator.repository()
71
+ class UserRepository implements IRepository<User, UserCriteria> {
72
+ private connection: unknown = null;
73
+
74
+ public async open(): Promise<unknown> {
75
+ // Open database connection
76
+ this.connection = await this.createConnection();
77
+ return this.connection;
78
+ }
79
+
80
+ public async close(): Promise<void> {
81
+ // Close database connection
82
+ this.connection = null;
83
+ }
84
+
85
+ public async find(
86
+ criteria: UserCriteria & { page?: number; limit?: number; q?: string }
87
+ ): Promise<FilterResultType<User>> {
88
+ const { page = 1, limit = 10, q, ...filters } = criteria;
89
+
90
+ // Query implementation
91
+ const users = await this.queryUsers(filters, q);
92
+ const total = await this.countUsers(filters, q);
93
+
94
+ return {
95
+ resources: users,
96
+ total,
97
+ totalPages: Math.ceil(total / limit),
98
+ page,
99
+ limit
100
+ };
101
+ }
102
+
103
+ private async createConnection(): Promise<unknown> {
104
+ // Connection logic
105
+ return {};
106
+ }
107
+
108
+ private async queryUsers(filters: UserCriteria, q?: string): Promise<User[]> {
109
+ // Query logic
110
+ return [];
111
+ }
112
+
113
+ private async countUsers(filters: UserCriteria, q?: string): Promise<number> {
114
+ // Count logic
115
+ return 0;
116
+ }
117
+ }
118
+ ```
119
+
120
+ ### Resolving Repositories
121
+
122
+ ```typescript
123
+ import { container } from '@ooneex/container';
124
+ import { UserRepository } from './repositories/UserRepository';
125
+
126
+ // Repository is automatically registered by the decorator
127
+ const userRepo = container.get(UserRepository);
128
+
129
+ // Open connection
130
+ await userRepo.open();
131
+
132
+ // Find users with pagination
133
+ const result = await userRepo.find({
134
+ isActive: true,
135
+ page: 1,
136
+ limit: 20,
137
+ q: 'john'
138
+ });
139
+
140
+ console.log(result.resources); // User[]
141
+ console.log(result.total); // Total count
142
+ console.log(result.totalPages); // Number of pages
143
+
144
+ // Close connection
145
+ await userRepo.close();
146
+ ```
147
+
148
+ ### Repository with TypeORM
149
+
150
+ ```typescript
151
+ import { decorator, type IRepository } from '@ooneex/repository';
152
+ import { container } from '@ooneex/container';
153
+ import type { FilterResultType } from '@ooneex/types';
154
+ import type { IDatabase } from '@ooneex/database';
155
+ import type { Repository } from 'typeorm';
156
+
157
+ interface Product {
158
+ id: string;
159
+ name: string;
160
+ price: number;
161
+ category: string;
162
+ }
163
+
164
+ interface ProductCriteria {
165
+ category?: string;
166
+ minPrice?: number;
167
+ maxPrice?: number;
168
+ }
169
+
170
+ @decorator.repository()
171
+ class ProductRepository implements IRepository<Product, ProductCriteria> {
172
+ private readonly database = container.get<IDatabase>('database');
173
+ private repository: Repository<Product> | null = null;
174
+
175
+ public async open(): Promise<Repository<Product>> {
176
+ this.repository = await this.database.open(ProductEntity);
177
+ return this.repository;
178
+ }
179
+
180
+ public async close(): Promise<void> {
181
+ // TypeORM manages connection lifecycle
182
+ }
183
+
184
+ public async find(
185
+ criteria: ProductCriteria & { page?: number; limit?: number; q?: string }
186
+ ): Promise<FilterResultType<Product>> {
187
+ const { page = 1, limit = 10, q, category, minPrice, maxPrice } = criteria;
188
+
189
+ const queryBuilder = this.repository!
190
+ .createQueryBuilder('product');
191
+
192
+ if (category) {
193
+ queryBuilder.andWhere('product.category = :category', { category });
194
+ }
195
+
196
+ if (minPrice !== undefined) {
197
+ queryBuilder.andWhere('product.price >= :minPrice', { minPrice });
198
+ }
199
+
200
+ if (maxPrice !== undefined) {
201
+ queryBuilder.andWhere('product.price <= :maxPrice', { maxPrice });
202
+ }
203
+
204
+ if (q) {
205
+ queryBuilder.andWhere('product.name ILIKE :q', { q: `%${q}%` });
206
+ }
207
+
208
+ const [resources, total] = await queryBuilder
209
+ .skip((page - 1) * limit)
210
+ .take(limit)
211
+ .getManyAndCount();
212
+
213
+ return {
214
+ resources,
215
+ total,
216
+ totalPages: Math.ceil(total / limit),
217
+ page,
218
+ limit
219
+ };
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### Transient Repositories
225
+
226
+ ```typescript
227
+ import { decorator, type IRepository } from '@ooneex/repository';
228
+ import { EContainerScope } from '@ooneex/container';
229
+
230
+ @decorator.repository(EContainerScope.Transient)
231
+ class TransientRepository implements IRepository {
232
+ private readonly instanceId = crypto.randomUUID();
233
+
234
+ public async open(): Promise<unknown> {
235
+ console.log(`Opening connection for instance: ${this.instanceId}`);
236
+ return {};
237
+ }
238
+
239
+ public async close(): Promise<void> {
240
+ console.log(`Closing connection for instance: ${this.instanceId}`);
241
+ }
242
+
243
+ public async find(criteria: { page?: number; limit?: number; q?: string }) {
244
+ return {
245
+ resources: [],
246
+ total: 0,
247
+ totalPages: 0,
248
+ page: criteria.page ?? 1,
249
+ limit: criteria.limit ?? 10
250
+ };
251
+ }
252
+ }
253
+
254
+ // Each resolution creates a new instance
255
+ const repo1 = container.get(TransientRepository);
256
+ const repo2 = container.get(TransientRepository);
257
+ // repo1 and repo2 have different instanceIds
258
+ ```
259
+
260
+ ## API Reference
261
+
262
+ ### Decorators
263
+
264
+ #### `@decorator.repository(scope?)`
265
+
266
+ Decorator to register a repository class with the DI container.
267
+
268
+ **Parameters:**
269
+ - `scope` - Container scope (default: `EContainerScope.Singleton`)
270
+ - `Singleton` - Single instance shared across all requests
271
+ - `Transient` - New instance created on every resolution
272
+ - `Request` - New instance per request context
273
+
274
+ **Example:**
275
+ ```typescript
276
+ import { decorator } from '@ooneex/repository';
277
+ import { EContainerScope } from '@ooneex/container';
278
+
279
+ // Singleton (default)
280
+ @decorator.repository()
281
+ class MySingletonRepository {}
282
+
283
+ // Transient
284
+ @decorator.repository(EContainerScope.Transient)
285
+ class MyTransientRepository {}
286
+
287
+ // Request-scoped
288
+ @decorator.repository(EContainerScope.Request)
289
+ class MyRequestRepository {}
290
+ ```
291
+
292
+ ### Interfaces
293
+
294
+ #### `IRepository<T, TCriteria>`
295
+
296
+ Interface for repository implementations.
297
+
298
+ ```typescript
299
+ interface IRepository<T = unknown, TCriteria = unknown> {
300
+ open: () => Promise<unknown>;
301
+ close: () => Promise<void>;
302
+ find: (criteria: TCriteria & { page?: number; limit?: number; q?: string }) => Promise<FilterResultType<T>>;
303
+ }
304
+ ```
305
+
306
+ **Type Parameters:**
307
+ - `T` - The entity type returned by the repository
308
+ - `TCriteria` - The criteria type for filtering results
309
+
310
+ **Methods:**
311
+
312
+ ##### `open(): Promise<unknown>`
313
+
314
+ Open or initialize the data source connection.
315
+
316
+ **Returns:** Promise resolving to the connection or data source
317
+
318
+ ##### `close(): Promise<void>`
319
+
320
+ Close the data source connection.
321
+
322
+ **Returns:** Promise that resolves when connection is closed
323
+
324
+ ##### `find(criteria): Promise<FilterResultType<T>>`
325
+
326
+ Find entities matching the given criteria with pagination support.
327
+
328
+ **Parameters:**
329
+ - `criteria` - Filter criteria including:
330
+ - Custom filter fields from `TCriteria`
331
+ - `page` - Page number (default: 1)
332
+ - `limit` - Items per page (default: 10)
333
+ - `q` - Search query string
334
+
335
+ **Returns:** Promise resolving to paginated results
336
+
337
+ ### Types
338
+
339
+ #### `RepositoryClassType`
340
+
341
+ Type for repository class constructors.
342
+
343
+ ```typescript
344
+ type RepositoryClassType = new (...args: any[]) => IRepository;
345
+ ```
346
+
347
+ #### `FilterResultType<T>`
348
+
349
+ Type for paginated query results (from @ooneex/types).
350
+
351
+ ```typescript
352
+ type FilterResultType<T> = {
353
+ resources: T[];
354
+ total: number;
355
+ totalPages: number;
356
+ page: number;
357
+ limit: number;
358
+ };
359
+ ```
360
+
361
+ ## Advanced Usage
362
+
363
+ ### Repository with Caching
364
+
365
+ ```typescript
366
+ import { decorator, type IRepository } from '@ooneex/repository';
367
+ import { container } from '@ooneex/container';
368
+ import type { ICache } from '@ooneex/cache';
369
+ import type { FilterResultType } from '@ooneex/types';
370
+
371
+ interface Article {
372
+ id: string;
373
+ title: string;
374
+ content: string;
375
+ }
376
+
377
+ @decorator.repository()
378
+ class CachedArticleRepository implements IRepository<Article> {
379
+ private readonly cache = container.get<ICache>('cache');
380
+
381
+ public async open(): Promise<unknown> {
382
+ return {};
383
+ }
384
+
385
+ public async close(): Promise<void> {}
386
+
387
+ public async find(
388
+ criteria: { page?: number; limit?: number; q?: string }
389
+ ): Promise<FilterResultType<Article>> {
390
+ const cacheKey = `articles:${JSON.stringify(criteria)}`;
391
+
392
+ // Check cache first
393
+ const cached = await this.cache.get<FilterResultType<Article>>(cacheKey);
394
+ if (cached) {
395
+ return cached;
396
+ }
397
+
398
+ // Query database
399
+ const result = await this.queryDatabase(criteria);
400
+
401
+ // Cache for 5 minutes
402
+ await this.cache.set(cacheKey, result, 300);
403
+
404
+ return result;
405
+ }
406
+
407
+ private async queryDatabase(
408
+ criteria: { page?: number; limit?: number; q?: string }
409
+ ): Promise<FilterResultType<Article>> {
410
+ // Database query logic
411
+ return {
412
+ resources: [],
413
+ total: 0,
414
+ totalPages: 0,
415
+ page: criteria.page ?? 1,
416
+ limit: criteria.limit ?? 10
417
+ };
418
+ }
419
+ }
420
+ ```
421
+
422
+ ### Repository with Logging
423
+
424
+ ```typescript
425
+ import { decorator, type IRepository } from '@ooneex/repository';
426
+ import { container } from '@ooneex/container';
427
+ import type { ILogger } from '@ooneex/logger';
428
+ import type { FilterResultType } from '@ooneex/types';
429
+
430
+ @decorator.repository()
431
+ class LoggedRepository<T> implements IRepository<T> {
432
+ private readonly logger = container.get<ILogger>('logger');
433
+
434
+ public async open(): Promise<unknown> {
435
+ this.logger.info('Opening repository connection');
436
+ const connection = await this.createConnection();
437
+ this.logger.success('Repository connection opened');
438
+ return connection;
439
+ }
440
+
441
+ public async close(): Promise<void> {
442
+ this.logger.info('Closing repository connection');
443
+ await this.closeConnection();
444
+ this.logger.success('Repository connection closed');
445
+ }
446
+
447
+ public async find(
448
+ criteria: { page?: number; limit?: number; q?: string }
449
+ ): Promise<FilterResultType<T>> {
450
+ this.logger.info('Finding resources', { criteria });
451
+
452
+ const startTime = Date.now();
453
+ const result = await this.queryResources(criteria);
454
+ const duration = Date.now() - startTime;
455
+
456
+ this.logger.info('Found resources', {
457
+ total: result.total,
458
+ page: result.page,
459
+ duration: `${duration}ms`
460
+ });
461
+
462
+ return result;
463
+ }
464
+
465
+ private async createConnection(): Promise<unknown> {
466
+ return {};
467
+ }
468
+
469
+ private async closeConnection(): Promise<void> {}
470
+
471
+ private async queryResources(
472
+ criteria: { page?: number; limit?: number; q?: string }
473
+ ): Promise<FilterResultType<T>> {
474
+ return {
475
+ resources: [],
476
+ total: 0,
477
+ totalPages: 0,
478
+ page: criteria.page ?? 1,
479
+ limit: criteria.limit ?? 10
480
+ };
481
+ }
482
+ }
483
+ ```
484
+
485
+ ### Abstract Base Repository
486
+
487
+ ```typescript
488
+ import { type IRepository } from '@ooneex/repository';
489
+ import type { FilterResultType } from '@ooneex/types';
490
+
491
+ abstract class BaseRepository<T, TCriteria = Record<string, unknown>>
492
+ implements IRepository<T, TCriteria> {
493
+
494
+ protected connection: unknown = null;
495
+
496
+ public async open(): Promise<unknown> {
497
+ this.connection = await this.createConnection();
498
+ return this.connection;
499
+ }
500
+
501
+ public async close(): Promise<void> {
502
+ await this.closeConnection();
503
+ this.connection = null;
504
+ }
505
+
506
+ public abstract find(
507
+ criteria: TCriteria & { page?: number; limit?: number; q?: string }
508
+ ): Promise<FilterResultType<T>>;
509
+
510
+ protected abstract createConnection(): Promise<unknown>;
511
+ protected abstract closeConnection(): Promise<void>;
512
+
513
+ protected paginate<R>(
514
+ resources: R[],
515
+ total: number,
516
+ page: number,
517
+ limit: number
518
+ ): FilterResultType<R> {
519
+ return {
520
+ resources,
521
+ total,
522
+ totalPages: Math.ceil(total / limit),
523
+ page,
524
+ limit
525
+ };
526
+ }
527
+ }
528
+
529
+ // Usage
530
+ @decorator.repository()
531
+ class OrderRepository extends BaseRepository<Order, OrderCriteria> {
532
+ protected async createConnection(): Promise<unknown> {
533
+ // Implementation
534
+ return {};
535
+ }
536
+
537
+ protected async closeConnection(): Promise<void> {
538
+ // Implementation
539
+ }
540
+
541
+ public async find(
542
+ criteria: OrderCriteria & { page?: number; limit?: number; q?: string }
543
+ ): Promise<FilterResultType<Order>> {
544
+ const { page = 1, limit = 10 } = criteria;
545
+
546
+ const orders = await this.queryOrders(criteria);
547
+ const total = await this.countOrders(criteria);
548
+
549
+ return this.paginate(orders, total, page, limit);
550
+ }
551
+ }
552
+ ```
553
+
554
+ ### Controller Integration
555
+
556
+ ```typescript
557
+ import { Route } from '@ooneex/routing';
558
+ import { container } from '@ooneex/container';
559
+ import type { IController, ContextType } from '@ooneex/controller';
560
+ import { UserRepository } from './repositories/UserRepository';
561
+
562
+ @Route.http({
563
+ name: 'api.users.list',
564
+ path: '/api/users',
565
+ method: 'GET',
566
+ description: 'List users with pagination'
567
+ })
568
+ class UserListController implements IController {
569
+ private readonly userRepository = container.get(UserRepository);
570
+
571
+ public async index(context: ContextType): Promise<IResponse> {
572
+ const { page, limit, q, ...filters } = context.queries;
573
+
574
+ const result = await this.userRepository.find({
575
+ ...filters,
576
+ page: Number(page) || 1,
577
+ limit: Number(limit) || 10,
578
+ q: q as string
579
+ });
580
+
581
+ return context.response.json(result);
582
+ }
583
+ }
584
+ ```
585
+
586
+ ### Testing Repositories
587
+
588
+ ```typescript
589
+ import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
590
+ import { container } from '@ooneex/container';
591
+ import { UserRepository } from './UserRepository';
592
+
593
+ describe('UserRepository', () => {
594
+ let repository: UserRepository;
595
+
596
+ beforeEach(async () => {
597
+ repository = container.get(UserRepository);
598
+ await repository.open();
599
+ });
600
+
601
+ afterEach(async () => {
602
+ await repository.close();
603
+ });
604
+
605
+ test('should return paginated results', async () => {
606
+ const result = await repository.find({ page: 1, limit: 10 });
607
+
608
+ expect(result).toHaveProperty('resources');
609
+ expect(result).toHaveProperty('total');
610
+ expect(result).toHaveProperty('totalPages');
611
+ expect(result).toHaveProperty('page', 1);
612
+ expect(result).toHaveProperty('limit', 10);
613
+ expect(Array.isArray(result.resources)).toBe(true);
614
+ });
615
+
616
+ test('should filter by criteria', async () => {
617
+ const result = await repository.find({
618
+ isActive: true,
619
+ page: 1,
620
+ limit: 10
621
+ });
622
+
623
+ expect(result.resources.every(user => user.isActive)).toBe(true);
624
+ });
625
+
626
+ test('should search with query string', async () => {
627
+ const result = await repository.find({
628
+ q: 'john',
629
+ page: 1,
630
+ limit: 10
631
+ });
632
+
633
+ expect(result.resources.every(
634
+ user => user.name.toLowerCase().includes('john')
635
+ )).toBe(true);
636
+ });
637
+ });
638
+ ```
639
+
640
+ ## License
641
+
642
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
643
+
644
+ ## Contributing
645
+
646
+ 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.
647
+
648
+ ### Development Setup
649
+
650
+ 1. Clone the repository
651
+ 2. Install dependencies: `bun install`
652
+ 3. Run tests: `bun run test`
653
+ 4. Build the project: `bun run build`
654
+
655
+ ### Guidelines
656
+
657
+ - Write tests for new features
658
+ - Follow the existing code style
659
+ - Update documentation for API changes
660
+ - Ensure all tests pass before submitting PR
661
+
662
+ ---
663
+
664
+ Made with ❤️ by the Ooneex team
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
+ import { EContainerScope } from "@ooneex/container";
1
2
  import { FilterResultType } from "@ooneex/types";
2
3
  type RepositoryClassType = new (...args: any[]) => IRepository;
3
4
  interface IRepository<
4
5
  T = unknown,
5
- TCriteria = unknown,
6
- TSaveOptions = unknown,
7
- TDeleteResult = unknown
6
+ TCriteria = unknown
8
7
  > {
9
8
  open: () => Promise<unknown>;
10
9
  close: () => Promise<void>;
@@ -13,13 +12,8 @@ interface IRepository<
13
12
  limit?: number;
14
13
  q?: string;
15
14
  }) => Promise<FilterResultType<T>>;
16
- findOne: (id: string) => Promise<T | null>;
17
- findOneBy: (criteria: TCriteria) => Promise<T | null>;
18
- create: (entity: T, options?: TSaveOptions) => Promise<T>;
19
- createMany: (entities: T[], options?: TSaveOptions) => Promise<T[]>;
20
- update: (entity: T, options?: TSaveOptions) => Promise<T>;
21
- updateMany: (entities: T[], options?: TSaveOptions) => Promise<T[]>;
22
- delete: (criteria: TCriteria | TCriteria[]) => Promise<TDeleteResult>;
23
- count: (criteria?: TCriteria | TCriteria[]) => Promise<number>;
24
15
  }
25
- export { RepositoryClassType, IRepository };
16
+ declare const decorator: {
17
+ repository: (scope?: EContainerScope) => (target: RepositoryClassType) => void;
18
+ };
19
+ export { decorator, RepositoryClassType, IRepository };
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
+ import{container as e,EContainerScope as t}from"@ooneex/container";var p={repository:(o=t.Singleton)=>{return(r)=>{e.add(r,o)}}};export{p as decorator};
1
2
 
2
- //# debugId=BC4C8D5165931A0D64756E2164756E21
3
+ //# debugId=1D18A0E1C9F4487464756E2164756E21
package/dist/index.js.map CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": [],
3
+ "sources": ["src/decorators.ts"],
4
4
  "sourcesContent": [
5
+ "import { container, EContainerScope } from \"@ooneex/container\";\nimport type { RepositoryClassType } from \"./types\";\n\nexport const decorator = {\n repository: (scope: EContainerScope = EContainerScope.Singleton) => {\n return (target: RepositoryClassType): void => {\n container.add(target, scope);\n };\n },\n};\n"
5
6
  ],
6
- "mappings": "",
7
- "debugId": "BC4C8D5165931A0D64756E2164756E21",
7
+ "mappings": "AAAA,oBAAS,qBAAW,0BAGb,IAAM,EAAY,CACvB,WAAY,CAAC,EAAyB,EAAgB,YAAc,CAClE,MAAO,CAAC,IAAsC,CAC5C,EAAU,IAAI,EAAQ,CAAK,GAGjC",
8
+ "debugId": "1D18A0E1C9F4487464756E2164756E21",
8
9
  "names": []
9
10
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ooneex/repository",
3
- "description": "",
4
- "version": "0.0.1",
3
+ "description": "Base repository classes and decorators for data access layer with dependency injection support",
4
+ "version": "0.0.4",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -25,11 +25,22 @@
25
25
  "test": "bun test tests",
26
26
  "build": "bunup",
27
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"
28
+ "publish": "bun publish --access public || true"
31
29
  },
32
- "dependencies": {},
33
- "devDependencies": {},
34
- "peerDependencies": {}
30
+ "dependencies": {
31
+ "@ooneex/container": "0.0.2"
32
+ },
33
+ "devDependencies": {
34
+ "@ooneex/types": "0.0.1"
35
+ },
36
+ "keywords": [
37
+ "bun",
38
+ "dao",
39
+ "data-access",
40
+ "decorator",
41
+ "ooneex",
42
+ "pattern",
43
+ "repository",
44
+ "typescript"
45
+ ]
35
46
  }
Binary file