mongolite-ts 0.6.0 → 0.7.2

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/dist/types.d.ts CHANGED
@@ -12,6 +12,14 @@ export interface InsertOneResult {
12
12
  acknowledged: boolean;
13
13
  insertedId: string;
14
14
  }
15
+ /**
16
+ * Result of insertMany operation.
17
+ */
18
+ export interface InsertManyResult {
19
+ acknowledged: boolean;
20
+ insertedCount: number;
21
+ insertedIds: Record<number, string>;
22
+ }
15
23
  /**
16
24
  * Result of updateOne operation.
17
25
  */
@@ -21,6 +29,13 @@ export interface UpdateResult {
21
29
  modifiedCount: number;
22
30
  upsertedId: string | null;
23
31
  }
32
+ /**
33
+ * Result of findOneAndUpdate/findOneAndReplace/findOneAndDelete operations.
34
+ */
35
+ export interface ModifyResult<T> {
36
+ value: T | null;
37
+ ok: 1;
38
+ }
24
39
  /**
25
40
  * Result of deleteOne/deleteMany operations.
26
41
  */
@@ -28,6 +43,46 @@ export interface DeleteResult {
28
43
  acknowledged: boolean;
29
44
  deletedCount: number;
30
45
  }
46
+ /**
47
+ * Options for findOneAndUpdate operations.
48
+ */
49
+ export interface FindOneAndUpdateOptions<TSchema = DocumentWithId> {
50
+ /** Whether to return the document before ('before') or after ('after') the update. Default is 'before'. */
51
+ returnDocument?: 'before' | 'after';
52
+ /** If true, insert a new document when no match is found. */
53
+ upsert?: boolean;
54
+ /** Field projection to apply. */
55
+ projection?: Projection<TSchema>;
56
+ }
57
+ /**
58
+ * Options for findOneAndDelete operations.
59
+ */
60
+ export interface FindOneAndDeleteOptions<TSchema = DocumentWithId> {
61
+ /** Field projection to apply. */
62
+ projection?: Projection<TSchema>;
63
+ }
64
+ /**
65
+ * Options for findOneAndReplace operations.
66
+ */
67
+ export interface FindOneAndReplaceOptions<TSchema = DocumentWithId> {
68
+ /** Whether to return the document before ('before') or after ('after') the replacement. Default is 'before'. */
69
+ returnDocument?: 'before' | 'after';
70
+ /** If true, insert a new document when no match is found. */
71
+ upsert?: boolean;
72
+ /** Field projection to apply. */
73
+ projection?: Projection<TSchema>;
74
+ }
75
+ /**
76
+ * Options for replaceOne operations.
77
+ */
78
+ export interface ReplaceOptions {
79
+ /** If true, insert a new document when no match is found. */
80
+ upsert?: boolean;
81
+ }
82
+ /**
83
+ * Options for aggregate operations.
84
+ */
85
+ export type AggregationPipeline = Record<string, unknown>[];
31
86
  /**
32
87
  * Operators for filtering documents.
33
88
  * T is the type of the field being queried.
@@ -44,6 +99,16 @@ export interface QueryOperators<T> {
44
99
  $all?: T extends unknown[] ? T : never;
45
100
  $exists?: boolean;
46
101
  $not?: QueryOperators<T>;
102
+ /** Regular expression pattern match. Can be a string pattern or RegExp object. */
103
+ $regex?: string | RegExp;
104
+ /** Regex options (flags). Used alongside $regex. E.g. 'i' for case-insensitive. */
105
+ $options?: string;
106
+ /** Matches arrays with the specified number of elements. */
107
+ $size?: number;
108
+ /** Selects documents where the value of the field is an instance of the specified BSON type. */
109
+ $type?: number | string | (number | string)[];
110
+ /** Matches documents where a field value divided by a divisor has a specified remainder. */
111
+ $mod?: [number, number];
47
112
  }
48
113
  /**
49
114
  * Logical filter operators.
@@ -104,6 +169,50 @@ export interface UpdateOperators<T> {
104
169
  } & {
105
170
  [key: string]: unknown;
106
171
  };
172
+ /** Adds a value to an array field only if the value is not already present. */
173
+ $addToSet?: {
174
+ [P in keyof T]?: unknown | {
175
+ $each: unknown[];
176
+ };
177
+ } & {
178
+ [key: string]: unknown | {
179
+ $each: unknown[];
180
+ };
181
+ };
182
+ /** Removes the first or last element from an array. Use 1 for last, -1 for first. */
183
+ $pop?: {
184
+ [P in keyof T]?: 1 | -1;
185
+ } & {
186
+ [key: string]: 1 | -1;
187
+ };
188
+ /** Multiplies the current value of a field by a number. */
189
+ $mul?: {
190
+ [P in keyof T]?: number;
191
+ } & {
192
+ [key: string]: number;
193
+ };
194
+ /** Updates the field value to the minimum of the current value and the specified value. */
195
+ $min?: {
196
+ [P in keyof T]?: T[P];
197
+ } & {
198
+ [key: string]: unknown;
199
+ };
200
+ /** Updates the field value to the maximum of the current value and the specified value. */
201
+ $max?: {
202
+ [P in keyof T]?: T[P];
203
+ } & {
204
+ [key: string]: unknown;
205
+ };
206
+ /** Sets the value of a field to the current date. */
207
+ $currentDate?: {
208
+ [P in keyof T]?: true | {
209
+ $type: 'date' | 'timestamp';
210
+ };
211
+ } & {
212
+ [key: string]: true | {
213
+ $type: 'date' | 'timestamp';
214
+ };
215
+ };
107
216
  }
108
217
  /**
109
218
  * UpdateFilter type for updating documents.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mongolite-ts",
3
- "version": "0.6.0",
3
+ "version": "0.7.2",
4
4
  "description": "A MongoDB-like client using SQLite as a persistent store, written in TypeScript.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -12,7 +12,9 @@
12
12
  "build": "tsc",
13
13
  "test": "node --import tsx --test tests/*.test.ts",
14
14
  "test:coverage": "c8 --reporter=lcov --reporter=text node --import tsx --test tests/*.test.ts",
15
+ "test:coverage:check": "c8 --reporter=lcov --reporter=text --check-coverage --lines 80 --functions 80 --statements 80 --branches 70 node --import tsx --test tests/*.test.ts",
15
16
  "prepare": "npm run build",
17
+ "prepublish": "npm run build",
16
18
  "lint": "eslint src/**/*.ts tests/**/*.ts",
17
19
  "lint:fix": "eslint src/**/*.ts tests/**/*.ts --fix",
18
20
  "verify-build": "node --import tsx scripts/verify-build.js",
@@ -42,10 +44,10 @@
42
44
  "homepage": "https://github.com/semics-tech/mongolite-ts#readme",
43
45
  "devDependencies": {
44
46
  "@types/better-sqlite3": "^7.6.13",
45
- "@types/node": "^24.0.7",
47
+ "@types/node": "^25.5.0",
46
48
  "@typescript-eslint/eslint-plugin": "^7.9.0",
47
49
  "@typescript-eslint/parser": "^7.9.0",
48
- "c8": "^10.1.3",
50
+ "c8": "^11.0.0",
49
51
  "eslint": "^8.57.0",
50
52
  "eslint-config-prettier": "^9.1.0",
51
53
  "eslint-plugin-prettier": "^5.1.3",
@@ -57,14 +59,14 @@
57
59
  "dependencies": {
58
60
  "@types/uuid": "^9.0.8",
59
61
  "better-sqlite3": "^12.1.1",
60
- "bson": "^6.10.4",
61
- "uuid": "^11.1.0"
62
+ "bson": "^7.2.0",
63
+ "uuid": "^13.0.0"
62
64
  },
63
65
  "files": [
64
66
  "dist/**/*",
65
67
  "README.md"
66
68
  ],
67
69
  "engines": {
68
- "node": ">=18.0.0"
70
+ "node": ">=20.0.0"
69
71
  }
70
72
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=database-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"database-manager.js","sourceRoot":"","sources":["../src/database-manager.ts"],"names":[],"mappings":""}
@@ -1,34 +0,0 @@
1
- /**
2
- * Utility functions for working with document objects
3
- */
4
- /**
5
- * Sets a nested value in an object using dot notation.
6
- * @param obj The object to modify.
7
- * @param path The dot notation path (e.g., 'user.profile.name').
8
- * @param value The value to set.
9
- */
10
- export declare function setNestedValue(obj: any, path: string, value: any): void;
11
- /**
12
- * Removes a nested property from an object using dot notation.
13
- * @param obj The object to modify.
14
- * @param path The dot notation path (e.g., 'user.profile.name').
15
- */
16
- export declare function unsetNestedValue(obj: any, path: string): void;
17
- /**
18
- * Gets a nested value from an object using dot notation.
19
- * @param obj The object to query.
20
- * @param path The dot notation path (e.g., 'user.profile.name').
21
- * @returns The value at the path, or undefined if the path doesn't exist.
22
- */
23
- export declare function getNestedValue(obj: any, path: string): any;
24
- /**
25
- * Generate a retry function with exponential backoff
26
- * @param operation The async operation to retry
27
- * @param operationDescription Description for logging
28
- * @param maxRetries Maximum number of retries
29
- * @param initialDelayMs Initial delay between retries (ms)
30
- * @param maxDelayMs Maximum delay between retries (ms)
31
- * @returns The result of the operation if successful
32
- * @throws The original error if all retries fail
33
- */
34
- export declare function retryWithBackoff<R>(operation: () => Promise<R>, operationDescription: string, maxRetries?: number, initialDelayMs?: number, maxDelayMs?: number): Promise<R>;
@@ -1,101 +0,0 @@
1
- /**
2
- * Utility functions for working with document objects
3
- */
4
- /**
5
- * Sets a nested value in an object using dot notation.
6
- * @param obj The object to modify.
7
- * @param path The dot notation path (e.g., 'user.profile.name').
8
- * @param value The value to set.
9
- */
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- export function setNestedValue(obj, path, value) {
12
- const keys = path.split('.');
13
- let current = obj;
14
- // Navigate to the last parent in the path
15
- for (let i = 0; i < keys.length - 1; i++) {
16
- const key = keys[i];
17
- // Create nested objects if they don't exist
18
- if (current[key] === undefined || current[key] === null) {
19
- current[key] = {};
20
- }
21
- else if (typeof current[key] !== 'object') {
22
- // If the path exists but is not an object, make it an object
23
- current[key] = {};
24
- }
25
- current = current[key];
26
- }
27
- // Set the value at the final key
28
- current[keys[keys.length - 1]] = value;
29
- }
30
- /**
31
- * Removes a nested property from an object using dot notation.
32
- * @param obj The object to modify.
33
- * @param path The dot notation path (e.g., 'user.profile.name').
34
- */
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- export function unsetNestedValue(obj, path) {
37
- const keys = path.split('.');
38
- let current = obj;
39
- // Navigate to the last parent in the path
40
- for (let i = 0; i < keys.length - 1; i++) {
41
- const key = keys[i];
42
- if (current[key] === undefined || current[key] === null) {
43
- // If the path doesn't exist, nothing to unset
44
- return;
45
- }
46
- current = current[key];
47
- }
48
- // Delete the property at the final key
49
- delete current[keys[keys.length - 1]];
50
- }
51
- /**
52
- * Gets a nested value from an object using dot notation.
53
- * @param obj The object to query.
54
- * @param path The dot notation path (e.g., 'user.profile.name').
55
- * @returns The value at the path, or undefined if the path doesn't exist.
56
- */
57
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
- export function getNestedValue(obj, path) {
59
- const keys = path.split('.');
60
- let current = obj;
61
- // Navigate through the path
62
- for (let i = 0; i < keys.length; i++) {
63
- const key = keys[i];
64
- if (current === undefined || current === null) {
65
- return undefined;
66
- }
67
- current = current[key];
68
- }
69
- return current;
70
- }
71
- /**
72
- * Generate a retry function with exponential backoff
73
- * @param operation The async operation to retry
74
- * @param operationDescription Description for logging
75
- * @param maxRetries Maximum number of retries
76
- * @param initialDelayMs Initial delay between retries (ms)
77
- * @param maxDelayMs Maximum delay between retries (ms)
78
- * @returns The result of the operation if successful
79
- * @throws The original error if all retries fail
80
- */
81
- export async function retryWithBackoff(operation, operationDescription, maxRetries = 5, initialDelayMs = 100, maxDelayMs = 10000) {
82
- let retries = 0;
83
- let delayMs = initialDelayMs;
84
- while (true) {
85
- try {
86
- return await operation();
87
- }
88
- catch (error) {
89
- if (error.code !== 'SQLITE_BUSY' || retries >= maxRetries) {
90
- throw error;
91
- }
92
- console.warn(`SQLITE_BUSY encountered during ${operationDescription}, retrying (${retries + 1}/${maxRetries})...`);
93
- // Wait for the backoff period
94
- await new Promise((resolve) => setTimeout(resolve, delayMs));
95
- // Increase delay for next retry (exponential backoff)
96
- delayMs = Math.min(delayMs * 2, maxDelayMs);
97
- retries++;
98
- }
99
- }
100
- }
101
- //# sourceMappingURL=document-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-utils.js","sourceRoot":"","sources":["../src/document-utils.ts"],"names":[],"mappings":"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"}
@@ -1,51 +0,0 @@
1
- import { DocumentWithId, Filter, SortCriteria, Projection } from './types.js';
2
- import { SQLiteDB } from './db.js';
3
- /**
4
- * Represents a cursor for find operations, allowing chaining of limit, skip, and sort.
5
- */
6
- export declare class FindCursor<T extends DocumentWithId> {
7
- private db;
8
- private collectionName;
9
- private readonly options;
10
- private queryParts;
11
- private limitCount;
12
- private skipCount;
13
- private sortCriteria;
14
- private projectionFields;
15
- private queryBuilder;
16
- constructor(db: SQLiteDB, collectionName: string, initialFilter: Filter<T>, options?: {
17
- verbose?: boolean;
18
- });
19
- private buildSelectQuery;
20
- /**
21
- * Specifies the maximum number of documents the cursor will return.
22
- * @param count The number of documents to limit to.
23
- * @returns The `FindCursor` instance for chaining.
24
- */
25
- limit(count: number): this;
26
- /**
27
- * Specifies the number of documents to skip.
28
- * @param count The number of documents to skip.
29
- * @returns The `FindCursor` instance for chaining.
30
- */
31
- skip(count: number): this;
32
- /**
33
- * Specifies the sorting order for the documents.
34
- * @param sortCriteria An object defining sort order (e.g., `{ age: -1, name: 1 }`).
35
- * @returns The `FindCursor` instance for chaining.
36
- */
37
- sort(sortCriteria: SortCriteria<T>): this;
38
- /**
39
- * Specifies the fields to return (projection).
40
- * @param projection An object where keys are field names and values are 1 (include) or 0 (exclude).
41
- * `_id` is included by default unless explicitly excluded.
42
- * @returns The `FindCursor` instance for chaining.
43
- */
44
- project(projection: Projection<T>): this;
45
- private applyProjection;
46
- /**
47
- * Executes the query and returns all matching documents as an array.
48
- * @returns A promise that resolves to an array of documents.
49
- */
50
- toArray(): Promise<Partial<T>[]>;
51
- }
@@ -1,204 +0,0 @@
1
- import { QueryBuilder } from './query-builder.js';
2
- /**
3
- * Represents a cursor for find operations, allowing chaining of limit, skip, and sort.
4
- */
5
- export class FindCursor {
6
- constructor(db, collectionName, initialFilter, options = {}) {
7
- this.db = db;
8
- this.collectionName = collectionName;
9
- this.options = options;
10
- this.limitCount = null;
11
- this.skipCount = null;
12
- this.sortCriteria = null;
13
- this.projectionFields = null;
14
- this.queryBuilder = new QueryBuilder(options);
15
- this.queryParts = this.buildSelectQuery(initialFilter);
16
- }
17
- buildSelectQuery(filter) {
18
- const params = [];
19
- const whereClause = this.queryBuilder.buildWhereClause(filter, params);
20
- const sql = `SELECT _id, data FROM "${this.collectionName}" WHERE ${whereClause}`;
21
- if (this.options.verbose) {
22
- console.log(`SQL Query: ${sql}`);
23
- console.log(`Parameters: ${JSON.stringify(params)}`);
24
- }
25
- return { sql, params };
26
- }
27
- /**
28
- * Specifies the maximum number of documents the cursor will return.
29
- * @param count The number of documents to limit to.
30
- * @returns The `FindCursor` instance for chaining.
31
- */
32
- limit(count) {
33
- if (count < 0)
34
- throw new Error('Limit must be a non-negative number.');
35
- this.limitCount = count;
36
- return this;
37
- }
38
- /**
39
- * Specifies the number of documents to skip.
40
- * @param count The number of documents to skip.
41
- * @returns The `FindCursor` instance for chaining.
42
- */
43
- skip(count) {
44
- if (count < 0)
45
- throw new Error('Skip must be a non-negative number.');
46
- this.skipCount = count;
47
- return this;
48
- }
49
- /**
50
- * Specifies the sorting order for the documents.
51
- * @param sortCriteria An object defining sort order (e.g., `{ age: -1, name: 1 }`).
52
- * @returns The `FindCursor` instance for chaining.
53
- */
54
- sort(sortCriteria) {
55
- this.sortCriteria = sortCriteria;
56
- return this;
57
- }
58
- /**
59
- * Specifies the fields to return (projection).
60
- * @param projection An object where keys are field names and values are 1 (include) or 0 (exclude).
61
- * `_id` is included by default unless explicitly excluded.
62
- * @returns The `FindCursor` instance for chaining.
63
- */
64
- project(projection) {
65
- this.projectionFields = projection;
66
- return this;
67
- }
68
- applyProjection(doc) {
69
- if (!this.projectionFields)
70
- return doc;
71
- const projectedDoc = {};
72
- let includeMode = true; // true if any field is 1, false if any field is 0 (excluding _id)
73
- let hasExplicitInclusion = false;
74
- // Determine if it's an inclusion or exclusion projection
75
- for (const key in this.projectionFields) {
76
- if (key === '_id')
77
- continue;
78
- if (this.projectionFields[key] === 1 ||
79
- this.projectionFields[key] === true) {
80
- hasExplicitInclusion = true;
81
- break;
82
- }
83
- if (this.projectionFields[key] === 0 ||
84
- this.projectionFields[key] === false) {
85
- includeMode = false;
86
- // No break here, need to check all for explicit inclusions if _id is also 0
87
- }
88
- }
89
- if ((this.projectionFields._id === 0 || this.projectionFields._id === false) &&
90
- !hasExplicitInclusion) {
91
- // If _id is excluded and no other fields are explicitly included,
92
- // it's an exclusion projection where other fields are implicitly included.
93
- includeMode = false;
94
- }
95
- else if (hasExplicitInclusion) {
96
- includeMode = true;
97
- }
98
- if (includeMode) {
99
- // Inclusion mode
100
- for (const key in this.projectionFields) {
101
- if (this.projectionFields[key] === 1 ||
102
- this.projectionFields[key] === true) {
103
- if (key.includes('.')) {
104
- // Handle nested paths for inclusion (basic implementation)
105
- const path = key.split('.');
106
- let current = doc;
107
- let target = projectedDoc;
108
- // Navigate to the last parent in the path
109
- for (let i = 0; i < path.length - 1; i++) {
110
- const segment = path[i];
111
- if (current[segment] === undefined)
112
- break;
113
- if (target[segment] === undefined) {
114
- target[segment] = {};
115
- }
116
- current = current[segment];
117
- target = target[segment];
118
- }
119
- // Set the final property if we reached it
120
- const lastSegment = path[path.length - 1];
121
- if (current && current[lastSegment] !== undefined) {
122
- target[lastSegment] = current[lastSegment];
123
- }
124
- }
125
- else if (key in doc) {
126
- projectedDoc[key] = doc[key];
127
- }
128
- }
129
- }
130
- // _id is included by default in inclusion mode, unless explicitly excluded
131
- if (this.projectionFields._id !== 0 && this.projectionFields._id !== false && '_id' in doc) {
132
- projectedDoc._id = doc._id;
133
- }
134
- }
135
- else {
136
- // Exclusion mode
137
- Object.assign(projectedDoc, doc);
138
- for (const key in this.projectionFields) {
139
- if (this.projectionFields[key] === 0 ||
140
- this.projectionFields[key] === false) {
141
- if (key.includes('.')) {
142
- // Handle nested paths for exclusion (basic implementation)
143
- const path = key.split('.');
144
- let current = projectedDoc;
145
- // Navigate to the parent of the property to exclude
146
- for (let i = 0; i < path.length - 1; i++) {
147
- const segment = path[i];
148
- if (current[segment] === undefined)
149
- break;
150
- current = current[segment];
151
- }
152
- // Delete the final property if we reached its parent
153
- const lastSegment = path[path.length - 1];
154
- if (current && current[lastSegment] !== undefined) {
155
- delete current[lastSegment];
156
- }
157
- }
158
- else {
159
- delete projectedDoc[key];
160
- }
161
- }
162
- }
163
- }
164
- return projectedDoc;
165
- }
166
- /**
167
- * Executes the query and returns all matching documents as an array.
168
- * @returns A promise that resolves to an array of documents.
169
- */
170
- async toArray() {
171
- let finalSql = this.queryParts.sql;
172
- const finalParams = [...this.queryParts.params];
173
- if (this.sortCriteria) {
174
- const sortClauses = Object.entries(this.sortCriteria).map(([field, order]) => {
175
- if (field === '_id') {
176
- return `_id ${order === 1 ? 'ASC' : 'DESC'}`;
177
- }
178
- return `json_extract(data, ${this.queryBuilder.parseJsonPath(field)}) ${order === 1 ? 'ASC' : 'DESC'}`;
179
- });
180
- if (sortClauses.length > 0) {
181
- finalSql += ` ORDER BY ${sortClauses.join(', ')}`;
182
- }
183
- }
184
- if (this.limitCount !== null) {
185
- finalSql += ` LIMIT ?`;
186
- finalParams.push(this.limitCount);
187
- }
188
- if (this.skipCount !== null) {
189
- if (this.limitCount === null) {
190
- // SQLite requires a LIMIT if OFFSET is used.
191
- // Use a very large number if no limit is specified.
192
- finalSql += ` LIMIT -1`; // Or a large number like 999999999
193
- }
194
- finalSql += ` OFFSET ?`;
195
- finalParams.push(this.skipCount);
196
- }
197
- const rows = await this.db.all(finalSql, finalParams);
198
- return rows.map((row) => {
199
- const doc = { _id: row._id, ...JSON.parse(row.data) };
200
- return this.applyProjection(doc);
201
- });
202
- }
203
- }
204
- //# sourceMappingURL=find-cursor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-cursor.js","sourceRoot":"","sources":["../src/find-cursor.ts"],"names":[],"mappings":"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"}