flongo 1.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/README.md +261 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +19 -0
- package/dist/flongo.d.ts +9 -0
- package/dist/flongo.js +10 -0
- package/dist/flongoCollection.d.ts +192 -0
- package/dist/flongoCollection.js +400 -0
- package/dist/flongoQuery.d.ts +230 -0
- package/dist/flongoQuery.js +448 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +23 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.js +49 -0
- package/package.json +59 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Logic = exports.FlongoQueryBuilder = exports.FlongoQuery = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
Object.defineProperty(exports, "Logic", { enumerable: true, get: function () { return types_1.Logic; } });
|
|
7
|
+
const geofire_common_1 = require("geofire-common");
|
|
8
|
+
const mongodb_1 = require("mongodb");
|
|
9
|
+
/**
|
|
10
|
+
* FlongoQuery provides a fluent, chainable interface for building MongoDB queries
|
|
11
|
+
* similar to Firestore's query API. It allows developers to construct complex queries
|
|
12
|
+
* using method chaining rather than building MongoDB filter objects manually.
|
|
13
|
+
*
|
|
14
|
+
* Example usage:
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const query = new FlongoQuery()
|
|
17
|
+
* .where('age').gtEq(18)
|
|
18
|
+
* .and('status').eq('active')
|
|
19
|
+
* .and('tags').arrContainsAny(['developer', 'designer'])
|
|
20
|
+
* .orderBy('createdAt', SortDirection.Descending);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
class FlongoQuery {
|
|
24
|
+
constructor() {
|
|
25
|
+
/** Array of field expressions (where conditions) */
|
|
26
|
+
this.expressions = [];
|
|
27
|
+
/** Array of range queries (currently unused but reserved for future features) */
|
|
28
|
+
this.ranges = [];
|
|
29
|
+
/** Array of queries to be combined with OR logic */
|
|
30
|
+
this.orQueries = [];
|
|
31
|
+
/** Array of queries to be combined with AND logic */
|
|
32
|
+
this.andQueries = [];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets the most recently added expression for method chaining
|
|
36
|
+
* @private
|
|
37
|
+
* @returns The last expression in the expressions array
|
|
38
|
+
*/
|
|
39
|
+
exp() {
|
|
40
|
+
return this.expressions[this.expressions.length - 1];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sets the operator and value for the most recent expression
|
|
44
|
+
* If value is null or undefined, removes the last expression (allows for conditional chaining)
|
|
45
|
+
* @private
|
|
46
|
+
* @param op - MongoDB operator (e.g., '$eq', '$gt', '$in')
|
|
47
|
+
* @param val - Value to compare against
|
|
48
|
+
* @returns This query instance for chaining
|
|
49
|
+
*/
|
|
50
|
+
set(op, val) {
|
|
51
|
+
if (val === null || val === undefined) {
|
|
52
|
+
// Remove the expression if no value is provided
|
|
53
|
+
// This allows conditional chaining like .where('field').eq(maybeUndefinedValue)
|
|
54
|
+
this.expressions.pop();
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
this.exp().op = op;
|
|
58
|
+
this.exp().val = val;
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Helper method to handle empty/invalid values by removing the last expression
|
|
63
|
+
* @private
|
|
64
|
+
* @returns This query instance for chaining
|
|
65
|
+
*/
|
|
66
|
+
handleEmptyValue() {
|
|
67
|
+
this.expressions.pop();
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Sets a range query on a field (currently unused but reserved for future features)
|
|
72
|
+
* @param key - Field name to query
|
|
73
|
+
* @param start - Start value of the range
|
|
74
|
+
* @param end - End value of the range
|
|
75
|
+
* @param orderField - Field to order by for range queries
|
|
76
|
+
*/
|
|
77
|
+
setRange(key, start, end, orderField) {
|
|
78
|
+
this.orderBy(orderField);
|
|
79
|
+
this.ranges.push({ key: key, start: start, end: end });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Starts a new where clause for the specified field
|
|
83
|
+
* @param key - Field name to query
|
|
84
|
+
* @returns This query instance for chaining
|
|
85
|
+
*/
|
|
86
|
+
where(key) {
|
|
87
|
+
this.expressions.push(new types_1.ColExpression(key));
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Alias for where() - adds another field constraint with AND logic
|
|
92
|
+
* @param key - Field name to query
|
|
93
|
+
* @returns This query instance for chaining
|
|
94
|
+
*/
|
|
95
|
+
and(key) {
|
|
96
|
+
this.where(key);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
// ===========================================
|
|
100
|
+
// COMPARISON OPERATORS
|
|
101
|
+
// ===========================================
|
|
102
|
+
/**
|
|
103
|
+
* Adds equality constraint to the current field
|
|
104
|
+
* @param val - Value to match exactly
|
|
105
|
+
* @returns This query instance for chaining
|
|
106
|
+
*/
|
|
107
|
+
eq(val) {
|
|
108
|
+
return this.set("$eq", val);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Adds not-equal constraint to the current field
|
|
112
|
+
* @param val - Value to exclude
|
|
113
|
+
* @returns This query instance for chaining
|
|
114
|
+
*/
|
|
115
|
+
neq(val) {
|
|
116
|
+
return this.set("$ne", val);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Adds less-than constraint to the current field
|
|
120
|
+
* @param val - Upper bound (exclusive)
|
|
121
|
+
* @returns This query instance for chaining
|
|
122
|
+
*/
|
|
123
|
+
lt(val) {
|
|
124
|
+
return this.set("$lt", val);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Adds less-than-or-equal constraint to the current field
|
|
128
|
+
* @param val - Upper bound (inclusive)
|
|
129
|
+
* @returns This query instance for chaining
|
|
130
|
+
*/
|
|
131
|
+
ltEq(val) {
|
|
132
|
+
return this.set("$lte", val);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Adds greater-than constraint to the current field
|
|
136
|
+
* @param val - Lower bound (exclusive)
|
|
137
|
+
* @returns This query instance for chaining
|
|
138
|
+
*/
|
|
139
|
+
gt(val) {
|
|
140
|
+
return this.set("$gt", val);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Adds greater-than-or-equal constraint to the current field
|
|
144
|
+
* @param val - Lower bound (inclusive)
|
|
145
|
+
* @returns This query instance for chaining
|
|
146
|
+
*/
|
|
147
|
+
gtEq(val) {
|
|
148
|
+
return this.set("$gte", val);
|
|
149
|
+
}
|
|
150
|
+
// ===========================================
|
|
151
|
+
// ARRAY OPERATORS
|
|
152
|
+
// ===========================================
|
|
153
|
+
/**
|
|
154
|
+
* Checks if array field contains the specified value
|
|
155
|
+
* @param val - Value that must be present in the array
|
|
156
|
+
* @returns This query instance for chaining
|
|
157
|
+
*/
|
|
158
|
+
arrContains(val) {
|
|
159
|
+
return this.set(undefined, val);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Checks if array field contains all of the specified values
|
|
163
|
+
* @param val - Array of values that must all be present
|
|
164
|
+
* @returns This query instance for chaining
|
|
165
|
+
*/
|
|
166
|
+
arrContainsAll(val) {
|
|
167
|
+
return this.set("$all", val);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Checks if array field contains any of the specified values
|
|
171
|
+
* If empty array is provided, removes the expression
|
|
172
|
+
* @param val - Array of values, any of which may be present
|
|
173
|
+
* @returns This query instance for chaining
|
|
174
|
+
*/
|
|
175
|
+
arrContainsAny(val) {
|
|
176
|
+
return val?.length ? this.set("$in", val) : this.handleEmptyValue();
|
|
177
|
+
}
|
|
178
|
+
// ===========================================
|
|
179
|
+
// STRING OPERATORS
|
|
180
|
+
// ===========================================
|
|
181
|
+
/**
|
|
182
|
+
* Adds case-insensitive string starts-with constraint
|
|
183
|
+
* @param val - String prefix to match
|
|
184
|
+
* @returns This query instance for chaining
|
|
185
|
+
*/
|
|
186
|
+
startsWith(val) {
|
|
187
|
+
return this.set("$regex", "^" + val);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Adds case-insensitive string ends-with constraint
|
|
191
|
+
* @param val - String suffix to match
|
|
192
|
+
* @returns This query instance for chaining
|
|
193
|
+
*/
|
|
194
|
+
endsWith(val) {
|
|
195
|
+
return this.set("$regex", val + "$");
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Adds case-insensitive string contains constraint
|
|
199
|
+
* @param val - Substring to search for
|
|
200
|
+
* @returns This query instance for chaining
|
|
201
|
+
*/
|
|
202
|
+
strContains(val) {
|
|
203
|
+
return this.set("$regex", val);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Helper method to apply comparison operators with null/empty checks
|
|
207
|
+
* @private
|
|
208
|
+
* @param op - MongoDB operator
|
|
209
|
+
* @param val - Array of values
|
|
210
|
+
* @returns This query instance for chaining
|
|
211
|
+
*/
|
|
212
|
+
applyComparisonOperator(op, val) {
|
|
213
|
+
if (val) {
|
|
214
|
+
this.set(op, val);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
// Remove expression if no values provided
|
|
218
|
+
this.expressions.pop();
|
|
219
|
+
}
|
|
220
|
+
return this;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Checks if field value is in the provided array
|
|
224
|
+
* @param val - Array of possible values
|
|
225
|
+
* @returns This query instance for chaining
|
|
226
|
+
*/
|
|
227
|
+
in(val) {
|
|
228
|
+
return val?.length ? this.applyComparisonOperator("$in", val) : this.handleEmptyValue();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Checks if field value is NOT in the provided array
|
|
232
|
+
* @param val - Array of values to exclude
|
|
233
|
+
* @returns This query instance for chaining
|
|
234
|
+
*/
|
|
235
|
+
notIn(val) {
|
|
236
|
+
return val?.length ? this.applyComparisonOperator("$nin", val) : this.handleEmptyValue();
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Convenience method for range queries (field >= min AND field <= max)
|
|
240
|
+
* @param key - Field name
|
|
241
|
+
* @param min - Minimum value (inclusive)
|
|
242
|
+
* @param max - Maximum value (inclusive)
|
|
243
|
+
* @returns This query instance for chaining
|
|
244
|
+
*/
|
|
245
|
+
inRange(key, min, max) {
|
|
246
|
+
return this.where(key).gtEq(min).and(key).ltEq(max);
|
|
247
|
+
}
|
|
248
|
+
// ===========================================
|
|
249
|
+
// GEOSPATIAL OPERATORS
|
|
250
|
+
// ===========================================
|
|
251
|
+
/**
|
|
252
|
+
* Performs geospatial radius search using geohash bounds
|
|
253
|
+
* This method uses the geofire-common library to generate geohash query bounds
|
|
254
|
+
* and creates OR queries for each bound to efficiently search within a radius
|
|
255
|
+
* @param key - Field containing geohash data
|
|
256
|
+
* @param center - Center point coordinates
|
|
257
|
+
* @param radius - Search radius in meters
|
|
258
|
+
* @returns This query instance for chaining
|
|
259
|
+
*/
|
|
260
|
+
inRadius(key, center, radius) {
|
|
261
|
+
// Generate geohash bounds for the given center and radius
|
|
262
|
+
const geoBounds = (0, geofire_common_1.geohashQueryBounds)([center.latitude, center.longitude], radius);
|
|
263
|
+
// Order by geohash field for optimal query performance
|
|
264
|
+
this.orderBy(key, types_1.SortDirection.Ascending);
|
|
265
|
+
// Create OR queries for each geohash bound range
|
|
266
|
+
for (const b of geoBounds) {
|
|
267
|
+
this.or(new FlongoQuery().inRange(key, b[0], b[1]));
|
|
268
|
+
}
|
|
269
|
+
return this;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Performs geospatial query within rectangular bounds
|
|
273
|
+
* Creates a GeoJSON polygon from the provided bounds
|
|
274
|
+
* @param bounds - Rectangular bounds with northeast and southwest corners
|
|
275
|
+
* @returns This query instance for chaining
|
|
276
|
+
*/
|
|
277
|
+
geoWithin(bounds) {
|
|
278
|
+
if (bounds) {
|
|
279
|
+
// Create GeoJSON polygon from bounds
|
|
280
|
+
// MongoDB requires coordinates in [longitude, latitude] format
|
|
281
|
+
// Polygon must be closed (first and last coordinates identical)
|
|
282
|
+
this.set("$geoWithin", {
|
|
283
|
+
$geometry: {
|
|
284
|
+
type: "Polygon",
|
|
285
|
+
coordinates: [
|
|
286
|
+
[
|
|
287
|
+
[bounds.ne.longitude, bounds.ne.latitude], // Top-right
|
|
288
|
+
[bounds.ne.longitude, bounds.sw.latitude], // Bottom-right
|
|
289
|
+
[bounds.sw.longitude, bounds.sw.latitude], // Bottom-left
|
|
290
|
+
[bounds.sw.longitude, bounds.ne.latitude], // Top-left
|
|
291
|
+
[bounds.ne.longitude, bounds.ne.latitude] // Close polygon
|
|
292
|
+
]
|
|
293
|
+
]
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// Remove expression if no bounds provided
|
|
299
|
+
this.expressions.pop();
|
|
300
|
+
}
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
// ===========================================
|
|
304
|
+
// SORTING
|
|
305
|
+
// ===========================================
|
|
306
|
+
/**
|
|
307
|
+
* Sets the field and direction for sorting results
|
|
308
|
+
* @param field - Field name to sort by
|
|
309
|
+
* @param direction - Sort direction (ascending or descending)
|
|
310
|
+
* @returns This query instance for chaining
|
|
311
|
+
*/
|
|
312
|
+
orderBy(field, direction) {
|
|
313
|
+
this.orderField = field;
|
|
314
|
+
this.orderDirection = direction;
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
// ===========================================
|
|
318
|
+
// LOGICAL OPERATORS
|
|
319
|
+
// ===========================================
|
|
320
|
+
/**
|
|
321
|
+
* Adds a sub-query with AND logic
|
|
322
|
+
* @param query - Sub-query to combine with AND logic
|
|
323
|
+
* @returns This query instance for chaining
|
|
324
|
+
*/
|
|
325
|
+
andQuery(query) {
|
|
326
|
+
this.andQueries.push(query);
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Adds a sub-query with OR logic
|
|
331
|
+
* @param query - Sub-query to combine with OR logic
|
|
332
|
+
* @returns This query instance for chaining
|
|
333
|
+
*/
|
|
334
|
+
or(query) {
|
|
335
|
+
this.orQueries.push(query);
|
|
336
|
+
return this;
|
|
337
|
+
}
|
|
338
|
+
// ===========================================
|
|
339
|
+
// QUERY BUILDING
|
|
340
|
+
// ===========================================
|
|
341
|
+
/**
|
|
342
|
+
* Builds the final MongoDB filter object from all expressions and sub-queries
|
|
343
|
+
* This method converts the fluent query structure into a MongoDB-compatible filter
|
|
344
|
+
* @returns MongoDB filter object
|
|
345
|
+
*/
|
|
346
|
+
build() {
|
|
347
|
+
let mongodbQuery = {};
|
|
348
|
+
try {
|
|
349
|
+
// Process main expressions
|
|
350
|
+
if (this.expressions) {
|
|
351
|
+
for (const expression of this.expressions) {
|
|
352
|
+
// Special handling for _id field - convert strings to ObjectIds
|
|
353
|
+
if (expression.key === "_id") {
|
|
354
|
+
if (Array.isArray(expression.val)) {
|
|
355
|
+
// Multiple IDs: {_id: {$in: [ObjectId(...), ObjectId(...)]}}
|
|
356
|
+
mongodbQuery = {
|
|
357
|
+
_id: {
|
|
358
|
+
[expression.op ?? "$in"]: expression.val.map((element) => new mongodb_1.ObjectId(element))
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
// Single ID: {_id: ObjectId(...)}
|
|
364
|
+
mongodbQuery = { _id: new mongodb_1.ObjectId(expression.val) };
|
|
365
|
+
}
|
|
366
|
+
break; // _id queries are typically exclusive
|
|
367
|
+
}
|
|
368
|
+
// Build query object for non-_id fields
|
|
369
|
+
const fieldValue = expression.op
|
|
370
|
+
? expression.op === "$regex"
|
|
371
|
+
? { [expression.op]: expression.val, ["$options"]: "i" } // Case-insensitive regex
|
|
372
|
+
: { [expression.op]: expression.val }
|
|
373
|
+
: expression.val; // Direct value assignment for simple equality
|
|
374
|
+
// Merge operators for the same field (e.g., range queries)
|
|
375
|
+
if (mongodbQuery[expression.key] &&
|
|
376
|
+
typeof mongodbQuery[expression.key] === "object" &&
|
|
377
|
+
typeof fieldValue === "object") {
|
|
378
|
+
mongodbQuery[expression.key] = { ...mongodbQuery[expression.key], ...fieldValue };
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
mongodbQuery[expression.key] = fieldValue;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Add OR sub-queries
|
|
386
|
+
if (this.orQueries.length > 0) {
|
|
387
|
+
mongodbQuery["$or"] = [];
|
|
388
|
+
for (const query of this.orQueries) {
|
|
389
|
+
mongodbQuery["$or"].push(query.build());
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Add AND sub-queries
|
|
393
|
+
if (this.andQueries.length > 0) {
|
|
394
|
+
mongodbQuery["$and"] = [];
|
|
395
|
+
for (const query of this.andQueries) {
|
|
396
|
+
mongodbQuery["$and"].push(query.build());
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
catch (err) {
|
|
401
|
+
console.log("Failed building query: ", err);
|
|
402
|
+
throw err;
|
|
403
|
+
}
|
|
404
|
+
// Note: Range queries are currently commented out but reserved for future use
|
|
405
|
+
// if (query.ranges) {
|
|
406
|
+
// query.ranges.forEach((range) => {
|
|
407
|
+
// mongodbQuery[range.key as keyof Filter<T>] = {
|
|
408
|
+
// $gte: range.start,
|
|
409
|
+
// $lt: range.end
|
|
410
|
+
// };
|
|
411
|
+
// });
|
|
412
|
+
// }
|
|
413
|
+
return mongodbQuery;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Builds MongoDB FindOptions for pagination and sorting
|
|
417
|
+
* @param pagination - Optional pagination settings
|
|
418
|
+
* @returns MongoDB FindOptions object
|
|
419
|
+
*/
|
|
420
|
+
buildOptions(pagination) {
|
|
421
|
+
const mongodbOptions = {};
|
|
422
|
+
// Add pagination if provided
|
|
423
|
+
if (pagination) {
|
|
424
|
+
mongodbOptions.skip = pagination.offset;
|
|
425
|
+
mongodbOptions.limit = pagination.count;
|
|
426
|
+
}
|
|
427
|
+
// Add sorting if specified
|
|
428
|
+
if (this.orderField && this.orderDirection) {
|
|
429
|
+
mongodbOptions.sort = {
|
|
430
|
+
[this.orderField]: this.orderDirection === types_1.SortDirection.Ascending ? 1 : -1
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return mongodbOptions;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
exports.FlongoQuery = FlongoQuery;
|
|
437
|
+
/**
|
|
438
|
+
* FlongoQueryBuilder provides a builder pattern wrapper around FlongoQuery
|
|
439
|
+
* This can be useful for more complex query construction scenarios
|
|
440
|
+
*/
|
|
441
|
+
class FlongoQueryBuilder {
|
|
442
|
+
constructor() {
|
|
443
|
+
/** The underlying query instance */
|
|
444
|
+
this.q = new FlongoQuery();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
exports.FlongoQueryBuilder = FlongoQueryBuilder;
|
|
448
|
+
//# sourceMappingURL=flongoQuery.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { FlongoCollection, FlongoCollectionOptions } from "./flongoCollection";
|
|
2
|
+
export { FlongoQuery, FlongoQueryBuilder } from "./flongoQuery";
|
|
3
|
+
export { initializeFlongo, FlongoConfig, flongoClient, flongoDb } from "./flongo";
|
|
4
|
+
export { Error404, Error400 } from "./errors";
|
|
5
|
+
export { Entity, DbRecord, Pagination, Coordinates, Bounds, Event, EventName, EventRecord, Logic, SortDirection, ColRange, ColExpression, ICollectionQuery, ICollection, Repository } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Main exports for flongo package
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ColExpression = exports.ColRange = exports.SortDirection = exports.Logic = exports.EventName = exports.Error400 = exports.Error404 = exports.flongoDb = exports.flongoClient = exports.initializeFlongo = exports.FlongoQueryBuilder = exports.FlongoQuery = exports.FlongoCollection = void 0;
|
|
5
|
+
var flongoCollection_1 = require("./flongoCollection");
|
|
6
|
+
Object.defineProperty(exports, "FlongoCollection", { enumerable: true, get: function () { return flongoCollection_1.FlongoCollection; } });
|
|
7
|
+
var flongoQuery_1 = require("./flongoQuery");
|
|
8
|
+
Object.defineProperty(exports, "FlongoQuery", { enumerable: true, get: function () { return flongoQuery_1.FlongoQuery; } });
|
|
9
|
+
Object.defineProperty(exports, "FlongoQueryBuilder", { enumerable: true, get: function () { return flongoQuery_1.FlongoQueryBuilder; } });
|
|
10
|
+
var flongo_1 = require("./flongo");
|
|
11
|
+
Object.defineProperty(exports, "initializeFlongo", { enumerable: true, get: function () { return flongo_1.initializeFlongo; } });
|
|
12
|
+
Object.defineProperty(exports, "flongoClient", { enumerable: true, get: function () { return flongo_1.flongoClient; } });
|
|
13
|
+
Object.defineProperty(exports, "flongoDb", { enumerable: true, get: function () { return flongo_1.flongoDb; } });
|
|
14
|
+
var errors_1 = require("./errors");
|
|
15
|
+
Object.defineProperty(exports, "Error404", { enumerable: true, get: function () { return errors_1.Error404; } });
|
|
16
|
+
Object.defineProperty(exports, "Error400", { enumerable: true, get: function () { return errors_1.Error400; } });
|
|
17
|
+
var types_1 = require("./types");
|
|
18
|
+
Object.defineProperty(exports, "EventName", { enumerable: true, get: function () { return types_1.EventName; } });
|
|
19
|
+
Object.defineProperty(exports, "Logic", { enumerable: true, get: function () { return types_1.Logic; } });
|
|
20
|
+
Object.defineProperty(exports, "SortDirection", { enumerable: true, get: function () { return types_1.SortDirection; } });
|
|
21
|
+
Object.defineProperty(exports, "ColRange", { enumerable: true, get: function () { return types_1.ColRange; } });
|
|
22
|
+
Object.defineProperty(exports, "ColExpression", { enumerable: true, get: function () { return types_1.ColExpression; } });
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export interface Entity {
|
|
2
|
+
_id: string;
|
|
3
|
+
createdAt: number;
|
|
4
|
+
updatedAt: number;
|
|
5
|
+
createdBy?: string;
|
|
6
|
+
updatedBy?: string;
|
|
7
|
+
}
|
|
8
|
+
export type DbRecord<T> = Entity & T;
|
|
9
|
+
export interface Pagination {
|
|
10
|
+
offset: number;
|
|
11
|
+
count: number;
|
|
12
|
+
}
|
|
13
|
+
export interface Coordinates {
|
|
14
|
+
latitude: number;
|
|
15
|
+
longitude: number;
|
|
16
|
+
geohash?: string;
|
|
17
|
+
geoJSON?: GeoJson;
|
|
18
|
+
}
|
|
19
|
+
export interface GeoJson {
|
|
20
|
+
type: string;
|
|
21
|
+
coordinates: number[];
|
|
22
|
+
}
|
|
23
|
+
export interface Bounds {
|
|
24
|
+
ne: Coordinates;
|
|
25
|
+
sw: Coordinates;
|
|
26
|
+
center?: Coordinates;
|
|
27
|
+
}
|
|
28
|
+
export declare enum EventName {
|
|
29
|
+
CreateEntity = "create_entity",
|
|
30
|
+
BatchCreateEntities = "batch_create_entities",
|
|
31
|
+
UpdateEntity = "update_entity",
|
|
32
|
+
BatchUpdateEntities = "batch_update_entities",
|
|
33
|
+
DeleteEntity = "delete_entity",
|
|
34
|
+
BatchDeleteEntities = "batch_delete_entities"
|
|
35
|
+
}
|
|
36
|
+
export type Event<T extends EventName = any> = {
|
|
37
|
+
name: T;
|
|
38
|
+
identity?: string;
|
|
39
|
+
value: any;
|
|
40
|
+
};
|
|
41
|
+
export type EventRecord<T extends EventName = any> = DbRecord<Event<T>>;
|
|
42
|
+
export declare enum Logic {
|
|
43
|
+
and = "and",
|
|
44
|
+
or = "or"
|
|
45
|
+
}
|
|
46
|
+
export declare enum SortDirection {
|
|
47
|
+
Ascending = "asc",
|
|
48
|
+
Descending = "desc"
|
|
49
|
+
}
|
|
50
|
+
export declare class ColRange {
|
|
51
|
+
key: string;
|
|
52
|
+
start: string;
|
|
53
|
+
end: string;
|
|
54
|
+
}
|
|
55
|
+
export declare class ColExpression {
|
|
56
|
+
op?: string | undefined;
|
|
57
|
+
key: string;
|
|
58
|
+
val: any;
|
|
59
|
+
constructor(key: string);
|
|
60
|
+
}
|
|
61
|
+
export type ICollectionQuery = {
|
|
62
|
+
expressions: ColExpression[];
|
|
63
|
+
ranges: ColRange[];
|
|
64
|
+
orderField?: string;
|
|
65
|
+
orderDirection?: SortDirection;
|
|
66
|
+
orQueries: ICollectionQuery[];
|
|
67
|
+
andQueries: ICollectionQuery[];
|
|
68
|
+
};
|
|
69
|
+
export type ICollection<T> = {
|
|
70
|
+
getAll: (query?: ICollectionQuery, pagination?: Pagination) => Promise<(Entity & T)[]>;
|
|
71
|
+
getSome: (query: ICollectionQuery, pagination: Pagination) => Promise<(Entity & T)[]>;
|
|
72
|
+
getFirst: (query: ICollectionQuery, pagination?: Pagination) => Promise<Entity & T>;
|
|
73
|
+
get: (id: string) => Promise<Entity & T>;
|
|
74
|
+
count: (query?: ICollectionQuery) => Promise<number>;
|
|
75
|
+
delete: (id: string, clientId?: string) => Promise<void>;
|
|
76
|
+
batchDelete: (ids: string[], clientId?: string) => Promise<void>;
|
|
77
|
+
exists: (query: ICollectionQuery) => Promise<boolean>;
|
|
78
|
+
create: (attributes: T, clientId?: string) => Promise<Entity & T>;
|
|
79
|
+
batchCreate: (attributes: T[], clientId?: string) => Promise<void>;
|
|
80
|
+
updateAll: (attributes: any, filters?: any, clientId?: string) => Promise<void>;
|
|
81
|
+
update: (id: string, attributes: any, clientId?: string) => Promise<void>;
|
|
82
|
+
increment: (id: string, key: string, amt?: number) => Promise<void>;
|
|
83
|
+
decrement: (id: string, key: string, amt?: number) => Promise<void>;
|
|
84
|
+
append: (id: string, key: string, items: any[]) => Promise<void>;
|
|
85
|
+
arrRemove: (id: string, key: string, items: any[]) => Promise<void>;
|
|
86
|
+
updateFirst: (attributes: any, filters?: any, clientId?: string) => Promise<Entity & T>;
|
|
87
|
+
};
|
|
88
|
+
export type Repository = string;
|
|
89
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Core types for flongo - extracted from @staysco/models
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ColExpression = exports.ColRange = exports.SortDirection = exports.Logic = exports.EventName = void 0;
|
|
5
|
+
// Event system types - making these generic for flongo
|
|
6
|
+
var EventName;
|
|
7
|
+
(function (EventName) {
|
|
8
|
+
EventName["CreateEntity"] = "create_entity";
|
|
9
|
+
EventName["BatchCreateEntities"] = "batch_create_entities";
|
|
10
|
+
EventName["UpdateEntity"] = "update_entity";
|
|
11
|
+
EventName["BatchUpdateEntities"] = "batch_update_entities";
|
|
12
|
+
EventName["DeleteEntity"] = "delete_entity";
|
|
13
|
+
EventName["BatchDeleteEntities"] = "batch_delete_entities";
|
|
14
|
+
})(EventName || (exports.EventName = EventName = {}));
|
|
15
|
+
// Enums for common operations
|
|
16
|
+
var Logic;
|
|
17
|
+
(function (Logic) {
|
|
18
|
+
Logic["and"] = "and";
|
|
19
|
+
Logic["or"] = "or";
|
|
20
|
+
})(Logic || (exports.Logic = Logic = {}));
|
|
21
|
+
var SortDirection;
|
|
22
|
+
(function (SortDirection) {
|
|
23
|
+
SortDirection["Ascending"] = "asc";
|
|
24
|
+
SortDirection["Descending"] = "desc";
|
|
25
|
+
})(SortDirection || (exports.SortDirection = SortDirection = {}));
|
|
26
|
+
// Collection operations
|
|
27
|
+
class ColRange {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.key = "";
|
|
30
|
+
this.start = "";
|
|
31
|
+
this.end = "";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.ColRange = ColRange;
|
|
35
|
+
class ColExpression {
|
|
36
|
+
constructor(key) {
|
|
37
|
+
this.op = "==";
|
|
38
|
+
this.key = "";
|
|
39
|
+
this.val = "";
|
|
40
|
+
if (this.key === "_id") {
|
|
41
|
+
this.key = String(key);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.key = key;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.ColExpression = ColExpression;
|
|
49
|
+
//# sourceMappingURL=types.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flongo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Firestore-like fluent query API for MongoDB",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"build:watch": "tsc --watch",
|
|
10
|
+
"dev": "tsc --watch",
|
|
11
|
+
"test": "vitest",
|
|
12
|
+
"test:watch": "vitest --watch",
|
|
13
|
+
"test:coverage": "vitest --coverage",
|
|
14
|
+
"lint": "echo 'Linting not configured yet'",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"prepublishOnly": "npm run build && npm test",
|
|
17
|
+
"semantic-release": "semantic-release"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mongodb",
|
|
21
|
+
"firestore",
|
|
22
|
+
"query",
|
|
23
|
+
"fluent",
|
|
24
|
+
"database",
|
|
25
|
+
"nosql"
|
|
26
|
+
],
|
|
27
|
+
"author": "Nick Schrock",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"mongodb": "^6.0.0",
|
|
31
|
+
"geofire-common": "^6.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.0.0",
|
|
35
|
+
"vitest": "^1.0.0",
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"semantic-release": "^22.0.0",
|
|
38
|
+
"@semantic-release/changelog": "^6.0.0",
|
|
39
|
+
"@semantic-release/git": "^10.0.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"mongodb": ">=5.0.0"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist/**/*.js",
|
|
46
|
+
"dist/**/*.d.ts",
|
|
47
|
+
"!dist/**/__tests__/**",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE"
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/nickrunner/flongo.git"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/nickrunner/flongo/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/nickrunner/flongo#readme"
|
|
59
|
+
}
|