@classytic/mongokit 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -12
- package/dist/actions/index.cjs +0 -479
- package/dist/actions/index.cjs.map +0 -1
- package/dist/actions/index.d.cts +0 -3
- package/dist/index-BfVJZF-3.d.cts +0 -337
- package/dist/index.cjs +0 -2142
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -239
- package/dist/memory-cache-DqfFfKes.d.cts +0 -142
- package/dist/pagination/PaginationEngine.cjs +0 -375
- package/dist/pagination/PaginationEngine.cjs.map +0 -1
- package/dist/pagination/PaginationEngine.d.cts +0 -117
- package/dist/plugins/index.cjs +0 -874
- package/dist/plugins/index.cjs.map +0 -1
- package/dist/plugins/index.d.cts +0 -275
- package/dist/types-Nxhmi1aI.d.cts +0 -510
- package/dist/utils/index.cjs +0 -667
- package/dist/utils/index.cjs.map +0 -1
- package/dist/utils/index.d.cts +0 -189
package/dist/index.d.cts
DELETED
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
import { A as AnyDocument, e as PluginType, P as PaginationConfig, S as SelectSpec, f as PopulateSpec, g as SortSpec, a as OffsetPaginationResult, b as KeysetPaginationResult, d as AggregatePaginationResult, R as RepositoryContext, H as HttpError } from './types-Nxhmi1aI.cjs';
|
|
2
|
-
export { c as AggregatePaginationOptions, i as AnyModel, N as CacheAdapter, T as CacheOperationOptions, Q as CacheOptions, W as CacheStats, C as CreateOptions, w as CrudSchemas, x as DecodedCursor, D as DeleteResult, E as EventPayload, F as FieldPreset, u as FieldRules, I as GroupResult, J as JsonSchema, K as KeysetPaginationOptions, L as Logger, G as LookupOptions, M as MinMaxResult, h as ObjectId, O as OffsetPaginationOptions, l as OperationOptions, k as PaginationResult, t as ParsedQuery, p as Plugin, q as PluginFunction, s as RepositoryEvent, r as RepositoryInstance, v as SchemaBuilderOptions, B as SoftDeleteOptions, j as SortDirection, m as UpdateManyResult, U as UpdateOptions, n as UpdateWithValidationResult, o as UserContext, z as ValidationChainOptions, V as ValidationResult, y as ValidatorDefinition } from './types-Nxhmi1aI.cjs';
|
|
3
|
-
import * as mongoose from 'mongoose';
|
|
4
|
-
import { Model, ClientSession, PipelineStage, PopulateOptions } from 'mongoose';
|
|
5
|
-
import { PaginationEngine } from './pagination/PaginationEngine.cjs';
|
|
6
|
-
export { aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, fieldFilterPlugin, immutableField, methodRegistryPlugin, mongoOperationsPlugin, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin } from './plugins/index.cjs';
|
|
7
|
-
export { b as createError, c as createFieldPreset, d as createMemoryCache, f as filterResponseData, g as getFieldsForUser, a as getMongooseProjection } from './memory-cache-DqfFfKes.cjs';
|
|
8
|
-
export { i as actions } from './index-BfVJZF-3.cjs';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Repository Pattern - Data Access Layer
|
|
12
|
-
*
|
|
13
|
-
* Event-driven, plugin-based abstraction for MongoDB operations
|
|
14
|
-
* Inspired by Meta & Stripe's repository patterns
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* const userRepo = new Repository(UserModel, [
|
|
19
|
-
* timestampPlugin(),
|
|
20
|
-
* softDeletePlugin(),
|
|
21
|
-
* ]);
|
|
22
|
-
*
|
|
23
|
-
* // Create
|
|
24
|
-
* const user = await userRepo.create({ name: 'John', email: 'john@example.com' });
|
|
25
|
-
*
|
|
26
|
-
* // Read with pagination
|
|
27
|
-
* const users = await userRepo.getAll({ page: 1, limit: 20, filters: { status: 'active' } });
|
|
28
|
-
*
|
|
29
|
-
* // Update
|
|
30
|
-
* const updated = await userRepo.update(user._id, { name: 'John Doe' });
|
|
31
|
-
*
|
|
32
|
-
* // Delete
|
|
33
|
-
* await userRepo.delete(user._id);
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
type HookListener = (data: any) => void | Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Production-grade repository for MongoDB
|
|
40
|
-
* Event-driven, plugin-based, with smart pagination
|
|
41
|
-
*/
|
|
42
|
-
declare class Repository<TDoc = AnyDocument> {
|
|
43
|
-
readonly Model: Model<TDoc>;
|
|
44
|
-
readonly model: string;
|
|
45
|
-
readonly _hooks: Map<string, HookListener[]>;
|
|
46
|
-
readonly _pagination: PaginationEngine<TDoc>;
|
|
47
|
-
[key: string]: unknown;
|
|
48
|
-
constructor(Model: Model<TDoc>, plugins?: PluginType[], paginationConfig?: PaginationConfig);
|
|
49
|
-
/**
|
|
50
|
-
* Register a plugin
|
|
51
|
-
*/
|
|
52
|
-
use(plugin: PluginType): this;
|
|
53
|
-
/**
|
|
54
|
-
* Register event listener
|
|
55
|
-
*/
|
|
56
|
-
on(event: string, listener: HookListener): this;
|
|
57
|
-
/**
|
|
58
|
-
* Emit event
|
|
59
|
-
*/
|
|
60
|
-
emit(event: string, data: unknown): void;
|
|
61
|
-
/**
|
|
62
|
-
* Create single document
|
|
63
|
-
*/
|
|
64
|
-
create(data: Record<string, unknown>, options?: {
|
|
65
|
-
session?: ClientSession;
|
|
66
|
-
}): Promise<TDoc>;
|
|
67
|
-
/**
|
|
68
|
-
* Create multiple documents
|
|
69
|
-
*/
|
|
70
|
-
createMany(dataArray: Record<string, unknown>[], options?: {
|
|
71
|
-
session?: ClientSession;
|
|
72
|
-
ordered?: boolean;
|
|
73
|
-
}): Promise<TDoc[]>;
|
|
74
|
-
/**
|
|
75
|
-
* Get document by ID
|
|
76
|
-
*/
|
|
77
|
-
getById(id: string, options?: {
|
|
78
|
-
select?: SelectSpec;
|
|
79
|
-
populate?: PopulateSpec;
|
|
80
|
-
lean?: boolean;
|
|
81
|
-
session?: ClientSession;
|
|
82
|
-
throwOnNotFound?: boolean;
|
|
83
|
-
skipCache?: boolean;
|
|
84
|
-
cacheTtl?: number;
|
|
85
|
-
}): Promise<TDoc | null>;
|
|
86
|
-
/**
|
|
87
|
-
* Get single document by query
|
|
88
|
-
*/
|
|
89
|
-
getByQuery(query: Record<string, unknown>, options?: {
|
|
90
|
-
select?: SelectSpec;
|
|
91
|
-
populate?: PopulateSpec;
|
|
92
|
-
lean?: boolean;
|
|
93
|
-
session?: ClientSession;
|
|
94
|
-
throwOnNotFound?: boolean;
|
|
95
|
-
skipCache?: boolean;
|
|
96
|
-
cacheTtl?: number;
|
|
97
|
-
}): Promise<TDoc | null>;
|
|
98
|
-
/**
|
|
99
|
-
* Unified pagination - auto-detects offset vs keyset based on params
|
|
100
|
-
*
|
|
101
|
-
* Auto-detection logic:
|
|
102
|
-
* - If params has 'cursor' or 'after' → uses keyset pagination (stream)
|
|
103
|
-
* - If params has 'pagination' or 'page' → uses offset pagination (paginate)
|
|
104
|
-
* - Else → defaults to offset pagination with page=1
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* // Offset pagination (page-based)
|
|
108
|
-
* await repo.getAll({ page: 1, limit: 50, filters: { status: 'active' } });
|
|
109
|
-
* await repo.getAll({ pagination: { page: 2, limit: 20 } });
|
|
110
|
-
*
|
|
111
|
-
* // Keyset pagination (cursor-based)
|
|
112
|
-
* await repo.getAll({ cursor: 'eyJ2Ij...', limit: 50 });
|
|
113
|
-
* await repo.getAll({ after: 'eyJ2Ij...', sort: { createdAt: -1 } });
|
|
114
|
-
*
|
|
115
|
-
* // Simple query (defaults to page 1)
|
|
116
|
-
* await repo.getAll({ filters: { status: 'active' } });
|
|
117
|
-
*
|
|
118
|
-
* // Skip cache for fresh data
|
|
119
|
-
* await repo.getAll({ filters: { status: 'active' } }, { skipCache: true });
|
|
120
|
-
*/
|
|
121
|
-
getAll(params?: {
|
|
122
|
-
filters?: Record<string, unknown>;
|
|
123
|
-
sort?: SortSpec | string;
|
|
124
|
-
cursor?: string;
|
|
125
|
-
after?: string;
|
|
126
|
-
page?: number;
|
|
127
|
-
pagination?: {
|
|
128
|
-
page?: number;
|
|
129
|
-
limit?: number;
|
|
130
|
-
};
|
|
131
|
-
limit?: number;
|
|
132
|
-
search?: string;
|
|
133
|
-
}, options?: {
|
|
134
|
-
select?: SelectSpec;
|
|
135
|
-
populate?: PopulateSpec;
|
|
136
|
-
lean?: boolean;
|
|
137
|
-
session?: ClientSession;
|
|
138
|
-
skipCache?: boolean;
|
|
139
|
-
cacheTtl?: number;
|
|
140
|
-
}): Promise<OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc>>;
|
|
141
|
-
/**
|
|
142
|
-
* Get or create document
|
|
143
|
-
*/
|
|
144
|
-
getOrCreate(query: Record<string, unknown>, createData: Record<string, unknown>, options?: {
|
|
145
|
-
session?: ClientSession;
|
|
146
|
-
}): Promise<TDoc | null>;
|
|
147
|
-
/**
|
|
148
|
-
* Count documents
|
|
149
|
-
*/
|
|
150
|
-
count(query?: Record<string, unknown>, options?: {
|
|
151
|
-
session?: ClientSession;
|
|
152
|
-
}): Promise<number>;
|
|
153
|
-
/**
|
|
154
|
-
* Check if document exists
|
|
155
|
-
*/
|
|
156
|
-
exists(query: Record<string, unknown>, options?: {
|
|
157
|
-
session?: ClientSession;
|
|
158
|
-
}): Promise<{
|
|
159
|
-
_id: unknown;
|
|
160
|
-
} | null>;
|
|
161
|
-
/**
|
|
162
|
-
* Update document by ID
|
|
163
|
-
*/
|
|
164
|
-
update(id: string, data: Record<string, unknown>, options?: {
|
|
165
|
-
select?: SelectSpec;
|
|
166
|
-
populate?: PopulateSpec;
|
|
167
|
-
lean?: boolean;
|
|
168
|
-
session?: ClientSession;
|
|
169
|
-
}): Promise<TDoc>;
|
|
170
|
-
/**
|
|
171
|
-
* Delete document by ID
|
|
172
|
-
*/
|
|
173
|
-
delete(id: string, options?: {
|
|
174
|
-
session?: ClientSession;
|
|
175
|
-
}): Promise<{
|
|
176
|
-
success: boolean;
|
|
177
|
-
message: string;
|
|
178
|
-
}>;
|
|
179
|
-
/**
|
|
180
|
-
* Execute aggregation pipeline
|
|
181
|
-
*/
|
|
182
|
-
aggregate<TResult = unknown>(pipeline: PipelineStage[], options?: {
|
|
183
|
-
session?: ClientSession;
|
|
184
|
-
}): Promise<TResult[]>;
|
|
185
|
-
/**
|
|
186
|
-
* Aggregate pipeline with pagination
|
|
187
|
-
* Best for: Complex queries, grouping, joins
|
|
188
|
-
*/
|
|
189
|
-
aggregatePaginate(options?: {
|
|
190
|
-
pipeline?: PipelineStage[];
|
|
191
|
-
page?: number;
|
|
192
|
-
limit?: number;
|
|
193
|
-
session?: ClientSession;
|
|
194
|
-
}): Promise<AggregatePaginationResult<TDoc>>;
|
|
195
|
-
/**
|
|
196
|
-
* Get distinct values
|
|
197
|
-
*/
|
|
198
|
-
distinct<T = unknown>(field: string, query?: Record<string, unknown>, options?: {
|
|
199
|
-
session?: ClientSession;
|
|
200
|
-
}): Promise<T[]>;
|
|
201
|
-
/**
|
|
202
|
-
* Execute callback within a transaction
|
|
203
|
-
*/
|
|
204
|
-
withTransaction<T>(callback: (session: ClientSession) => Promise<T>): Promise<T>;
|
|
205
|
-
/**
|
|
206
|
-
* Execute custom query with event emission
|
|
207
|
-
*/
|
|
208
|
-
_executeQuery<T>(buildQuery: (Model: Model<TDoc>) => Promise<T>): Promise<T>;
|
|
209
|
-
/**
|
|
210
|
-
* Build operation context and run before hooks
|
|
211
|
-
*/
|
|
212
|
-
_buildContext(operation: string, options: Record<string, unknown>): Promise<RepositoryContext>;
|
|
213
|
-
/**
|
|
214
|
-
* Parse sort string or object
|
|
215
|
-
*/
|
|
216
|
-
_parseSort(sort: SortSpec | string | undefined): SortSpec;
|
|
217
|
-
/**
|
|
218
|
-
* Parse populate specification
|
|
219
|
-
*/
|
|
220
|
-
_parsePopulate(populate: PopulateSpec | undefined): string[] | PopulateOptions[];
|
|
221
|
-
/**
|
|
222
|
-
* Handle errors with proper HTTP status codes
|
|
223
|
-
*/
|
|
224
|
-
_handleError(error: Error): HttpError;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Factory function to create a repository instance
|
|
229
|
-
*
|
|
230
|
-
* @param Model - Mongoose model
|
|
231
|
-
* @param plugins - Array of plugins to apply
|
|
232
|
-
* @returns Repository instance
|
|
233
|
-
*
|
|
234
|
-
* @example
|
|
235
|
-
* const userRepo = createRepository(UserModel, [timestampPlugin()]);
|
|
236
|
-
*/
|
|
237
|
-
declare function createRepository<TDoc>(Model: mongoose.Model<TDoc>, plugins?: PluginType[]): Repository<TDoc>;
|
|
238
|
-
|
|
239
|
-
export { AggregatePaginationResult, AnyDocument, HttpError, KeysetPaginationResult, OffsetPaginationResult, PaginationConfig, PaginationEngine, PluginType, PopulateSpec, Repository, RepositoryContext, SelectSpec, SortSpec, createRepository, Repository as default };
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { o as UserContext, F as FieldPreset, H as HttpError, N as CacheAdapter } from './types-Nxhmi1aI.cjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Field Selection Utilities
|
|
5
|
-
*
|
|
6
|
-
* Provides explicit, performant field filtering using Mongoose projections.
|
|
7
|
-
*
|
|
8
|
-
* Philosophy:
|
|
9
|
-
* - Explicit is better than implicit
|
|
10
|
-
* - Filter at DB level (10x faster than in-memory)
|
|
11
|
-
* - Progressive disclosure (show more fields as trust increases)
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* // For Mongoose queries (PREFERRED - 90% of cases)
|
|
16
|
-
* const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);
|
|
17
|
-
* const plans = await GymPlan.find().select(projection).lean();
|
|
18
|
-
*
|
|
19
|
-
* // For complex data (10% of cases - aggregations, multiple sources)
|
|
20
|
-
* const filtered = filterResponseData(complexData, fieldPresets.gymPlans, request.user);
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get allowed fields for a user based on their context
|
|
26
|
-
*
|
|
27
|
-
* @param user - User object from request.user (or null for public)
|
|
28
|
-
* @param preset - Field preset configuration
|
|
29
|
-
* @returns Array of allowed field names
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* const fields = getFieldsForUser(request.user, {
|
|
33
|
-
* public: ['id', 'name', 'price'],
|
|
34
|
-
* authenticated: ['description', 'features'],
|
|
35
|
-
* admin: ['createdAt', 'internalNotes']
|
|
36
|
-
* });
|
|
37
|
-
*/
|
|
38
|
-
declare function getFieldsForUser(user: UserContext | null | undefined, preset: FieldPreset): string[];
|
|
39
|
-
/**
|
|
40
|
-
* Get Mongoose projection string for query .select()
|
|
41
|
-
*
|
|
42
|
-
* @param user - User object from request.user
|
|
43
|
-
* @param preset - Field preset configuration
|
|
44
|
-
* @returns Space-separated field names for Mongoose .select()
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);
|
|
48
|
-
* const plans = await GymPlan.find({ organizationId }).select(projection).lean();
|
|
49
|
-
*/
|
|
50
|
-
declare function getMongooseProjection(user: UserContext | null | undefined, preset: FieldPreset): string;
|
|
51
|
-
/**
|
|
52
|
-
* Filter response data to include only allowed fields
|
|
53
|
-
*
|
|
54
|
-
* Use this for complex responses where Mongoose projections aren't applicable:
|
|
55
|
-
* - Aggregation pipeline results
|
|
56
|
-
* - Data from multiple sources
|
|
57
|
-
* - Custom computed fields
|
|
58
|
-
*
|
|
59
|
-
* For simple DB queries, prefer getMongooseProjection() (10x faster)
|
|
60
|
-
*
|
|
61
|
-
* @param data - Data to filter
|
|
62
|
-
* @param preset - Field preset configuration
|
|
63
|
-
* @param user - User object from request.user
|
|
64
|
-
* @returns Filtered data
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* const stats = await calculateComplexStats();
|
|
68
|
-
* const filtered = filterResponseData(stats, fieldPresets.dashboard, request.user);
|
|
69
|
-
* return reply.send(filtered);
|
|
70
|
-
*/
|
|
71
|
-
declare function filterResponseData<T extends Record<string, unknown>>(data: T | T[], preset: FieldPreset, user?: UserContext | null): Partial<T> | Partial<T>[];
|
|
72
|
-
/**
|
|
73
|
-
* Helper to create field presets (module-level)
|
|
74
|
-
*
|
|
75
|
-
* Each module should define its own field preset in its own directory.
|
|
76
|
-
* This keeps modules independent and self-contained.
|
|
77
|
-
*
|
|
78
|
-
* @param config - Field configuration
|
|
79
|
-
* @returns Field preset
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* // In modules/gym-plan/gym-plan.fields.ts
|
|
83
|
-
* export const gymPlanFieldPreset = createFieldPreset({
|
|
84
|
-
* public: ['id', 'name', 'price'],
|
|
85
|
-
* authenticated: ['features', 'description'],
|
|
86
|
-
* admin: ['createdAt', 'updatedAt', 'internalNotes']
|
|
87
|
-
* });
|
|
88
|
-
*/
|
|
89
|
-
declare function createFieldPreset(config: Partial<FieldPreset>): FieldPreset;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Error Utilities
|
|
93
|
-
*
|
|
94
|
-
* HTTP-compatible error creation for repository operations
|
|
95
|
-
*/
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Creates an error with HTTP status code
|
|
99
|
-
*
|
|
100
|
-
* @param status - HTTP status code
|
|
101
|
-
* @param message - Error message
|
|
102
|
-
* @returns Error with status property
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* throw createError(404, 'Document not found');
|
|
106
|
-
* throw createError(400, 'Invalid input');
|
|
107
|
-
* throw createError(403, 'Access denied');
|
|
108
|
-
*/
|
|
109
|
-
declare function createError(status: number, message: string): HttpError;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* In-Memory Cache Adapter
|
|
113
|
-
*
|
|
114
|
-
* Simple cache adapter for development and testing.
|
|
115
|
-
* NOT recommended for production - use Redis or similar.
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* import { cachePlugin, createMemoryCache } from '@classytic/mongokit';
|
|
120
|
-
*
|
|
121
|
-
* const repo = new Repository(UserModel, [
|
|
122
|
-
* cachePlugin({
|
|
123
|
-
* adapter: createMemoryCache(),
|
|
124
|
-
* ttl: 60,
|
|
125
|
-
* })
|
|
126
|
-
* ]);
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Creates an in-memory cache adapter
|
|
132
|
-
*
|
|
133
|
-
* Features:
|
|
134
|
-
* - Automatic TTL expiration
|
|
135
|
-
* - Pattern-based clearing (simple glob with *)
|
|
136
|
-
* - Max entries limit to prevent memory leaks
|
|
137
|
-
*
|
|
138
|
-
* @param maxEntries - Maximum cache entries before oldest are evicted (default: 1000)
|
|
139
|
-
*/
|
|
140
|
-
declare function createMemoryCache(maxEntries?: number): CacheAdapter;
|
|
141
|
-
|
|
142
|
-
export { getMongooseProjection as a, createError as b, createFieldPreset as c, createMemoryCache as d, filterResponseData as f, getFieldsForUser as g };
|