@procedures/mongo 0.0.0-stage → 0.2.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/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +1322 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/connection.d.ts +93 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +147 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +26 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +66 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/collections.create.d.ts +21 -0
- package/dist/procedures/collections.create.d.ts.map +1 -0
- package/dist/procedures/collections.create.js +46 -0
- package/dist/procedures/collections.create.js.map +1 -0
- package/dist/procedures/collections.drop.d.ts +20 -0
- package/dist/procedures/collections.drop.d.ts.map +1 -0
- package/dist/procedures/collections.drop.js +40 -0
- package/dist/procedures/collections.drop.js.map +1 -0
- package/dist/procedures/collections.list.d.ts +17 -0
- package/dist/procedures/collections.list.d.ts.map +1 -0
- package/dist/procedures/collections.list.js +34 -0
- package/dist/procedures/collections.list.js.map +1 -0
- package/dist/procedures/collections.stats.d.ts +16 -0
- package/dist/procedures/collections.stats.d.ts.map +1 -0
- package/dist/procedures/collections.stats.js +41 -0
- package/dist/procedures/collections.stats.js.map +1 -0
- package/dist/procedures/database.info.d.ts +16 -0
- package/dist/procedures/database.info.d.ts.map +1 -0
- package/dist/procedures/database.info.js +41 -0
- package/dist/procedures/database.info.js.map +1 -0
- package/dist/procedures/database.ping.d.ts +18 -0
- package/dist/procedures/database.ping.d.ts.map +1 -0
- package/dist/procedures/database.ping.js +34 -0
- package/dist/procedures/database.ping.js.map +1 -0
- package/dist/procedures/documents.aggregate.d.ts +20 -0
- package/dist/procedures/documents.aggregate.d.ts.map +1 -0
- package/dist/procedures/documents.aggregate.js +43 -0
- package/dist/procedures/documents.aggregate.js.map +1 -0
- package/dist/procedures/documents.count.d.ts +19 -0
- package/dist/procedures/documents.count.d.ts.map +1 -0
- package/dist/procedures/documents.count.js +32 -0
- package/dist/procedures/documents.count.js.map +1 -0
- package/dist/procedures/documents.delete.d.ts +18 -0
- package/dist/procedures/documents.delete.d.ts.map +1 -0
- package/dist/procedures/documents.delete.js +34 -0
- package/dist/procedures/documents.delete.js.map +1 -0
- package/dist/procedures/documents.find.d.ts +24 -0
- package/dist/procedures/documents.find.d.ts.map +1 -0
- package/dist/procedures/documents.find.js +106 -0
- package/dist/procedures/documents.find.js.map +1 -0
- package/dist/procedures/documents.get.d.ts +21 -0
- package/dist/procedures/documents.get.d.ts.map +1 -0
- package/dist/procedures/documents.get.js +57 -0
- package/dist/procedures/documents.get.js.map +1 -0
- package/dist/procedures/documents.insert.d.ts +22 -0
- package/dist/procedures/documents.insert.d.ts.map +1 -0
- package/dist/procedures/documents.insert.js +58 -0
- package/dist/procedures/documents.insert.js.map +1 -0
- package/dist/procedures/documents.update.d.ts +27 -0
- package/dist/procedures/documents.update.d.ts.map +1 -0
- package/dist/procedures/documents.update.js +64 -0
- package/dist/procedures/documents.update.js.map +1 -0
- package/dist/procedures/index.d.ts +21 -0
- package/dist/procedures/index.d.ts.map +1 -0
- package/dist/procedures/index.js +26 -0
- package/dist/procedures/index.js.map +1 -0
- package/dist/procedures/indexes.create.d.ts +21 -0
- package/dist/procedures/indexes.create.d.ts.map +1 -0
- package/dist/procedures/indexes.create.js +48 -0
- package/dist/procedures/indexes.create.js.map +1 -0
- package/dist/procedures/indexes.drop.d.ts +18 -0
- package/dist/procedures/indexes.drop.d.ts.map +1 -0
- package/dist/procedures/indexes.drop.js +33 -0
- package/dist/procedures/indexes.drop.js.map +1 -0
- package/dist/procedures/indexes.list.d.ts +18 -0
- package/dist/procedures/indexes.list.d.ts.map +1 -0
- package/dist/procedures/indexes.list.js +43 -0
- package/dist/procedures/indexes.list.js.map +1 -0
- package/dist/procedures/input-schemas.d.ts +45 -0
- package/dist/procedures/input-schemas.d.ts.map +1 -0
- package/dist/procedures/input-schemas.js +52 -0
- package/dist/procedures/input-schemas.js.map +1 -0
- package/dist/procedures/schema.d.ts +2 -0
- package/dist/procedures/schema.d.ts.map +1 -0
- package/dist/procedures/schema.js +2 -0
- package/dist/procedures/schema.js.map +1 -0
- package/dist/procedures/target.d.ts +44 -0
- package/dist/procedures/target.d.ts.map +1 -0
- package/dist/procedures/target.js +98 -0
- package/dist/procedures/target.js.map +1 -0
- package/dist/procedures.types.d.ts +129 -0
- package/dist/procedures.types.d.ts.map +1 -0
- package/dist/procedures.types.js +24 -0
- package/dist/procedures.types.js.map +1 -0
- package/dist/register.d.ts +7 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +9 -0
- package/dist/register.js.map +1 -0
- package/dist/scope.d.ts +33 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +52 -0
- package/dist/scope.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/mongo-storage.d.ts +50 -0
- package/dist/storage/mongo-storage.d.ts.map +1 -0
- package/dist/storage/mongo-storage.js +109 -0
- package/dist/storage/mongo-storage.js.map +1 -0
- package/dist/types.d.ts +239 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +58 -0
- package/dist/types.js.map +1 -0
- package/package.json +84 -3
- package/src/connection.ts +198 -0
- package/src/index.ts +159 -0
- package/src/module.ts +71 -0
- package/src/procedures/collections.create.ts +72 -0
- package/src/procedures/collections.drop.ts +66 -0
- package/src/procedures/collections.list.ts +56 -0
- package/src/procedures/collections.stats.ts +60 -0
- package/src/procedures/database.info.ts +61 -0
- package/src/procedures/database.ping.ts +57 -0
- package/src/procedures/documents.aggregate.ts +72 -0
- package/src/procedures/documents.count.ts +55 -0
- package/src/procedures/documents.delete.ts +57 -0
- package/src/procedures/documents.find.ts +151 -0
- package/src/procedures/documents.get.ts +102 -0
- package/src/procedures/documents.insert.ts +86 -0
- package/src/procedures/documents.update.ts +96 -0
- package/src/procedures/index.ts +30 -0
- package/src/procedures/indexes.create.ts +74 -0
- package/src/procedures/indexes.drop.ts +56 -0
- package/src/procedures/indexes.list.ts +67 -0
- package/src/procedures/input-schemas.ts +63 -0
- package/src/procedures/schema.ts +1 -0
- package/src/procedures/target.ts +123 -0
- package/src/procedures.types.ts +162 -0
- package/src/register.ts +11 -0
- package/src/scope.ts +69 -0
- package/src/storage/index.ts +6 -0
- package/src/storage/mongo-storage.ts +151 -0
- package/src/types.ts +337 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for client-mongo procedures
|
|
3
|
+
*/
|
|
4
|
+
import { ObjectId } from "mongodb";
|
|
5
|
+
import type { Document, Filter, UpdateFilter } from "mongodb";
|
|
6
|
+
/**
|
|
7
|
+
* Pagination input parameters
|
|
8
|
+
*/
|
|
9
|
+
export interface PaginationInput {
|
|
10
|
+
/** Page number (1-indexed, default: 1) */
|
|
11
|
+
page?: number;
|
|
12
|
+
/** Items per page (default: 20, max: 100) */
|
|
13
|
+
limit?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Pagination output metadata
|
|
17
|
+
*/
|
|
18
|
+
export interface PaginationOutput {
|
|
19
|
+
/** Current page number */
|
|
20
|
+
page: number;
|
|
21
|
+
/** Items per page */
|
|
22
|
+
limit: number;
|
|
23
|
+
/** Total number of items */
|
|
24
|
+
total: number;
|
|
25
|
+
/** Total number of pages */
|
|
26
|
+
totalPages: number;
|
|
27
|
+
/** Whether there is a next page */
|
|
28
|
+
hasNext: boolean;
|
|
29
|
+
/** Whether there is a previous page */
|
|
30
|
+
hasPrev: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Sort order for queries
|
|
34
|
+
*/
|
|
35
|
+
export type SortOrder = 1 | -1;
|
|
36
|
+
/**
|
|
37
|
+
* Sort specification
|
|
38
|
+
*/
|
|
39
|
+
export type SortSpec = Record<string, SortOrder>;
|
|
40
|
+
/**
|
|
41
|
+
* Document ID - can be string or ObjectId.
|
|
42
|
+
* MongoDB supports any type for _id, but string and ObjectId are most common.
|
|
43
|
+
*/
|
|
44
|
+
export type DocumentId = string | ObjectId;
|
|
45
|
+
/**
|
|
46
|
+
* Base document type.
|
|
47
|
+
* Uses MongoDB's Document type which allows any _id via index signature.
|
|
48
|
+
*/
|
|
49
|
+
export type BaseDocument = Document;
|
|
50
|
+
/**
|
|
51
|
+
* Generic document type - use BaseDocument for proper _id typing
|
|
52
|
+
*/
|
|
53
|
+
export type MongoDocument = BaseDocument;
|
|
54
|
+
/**
|
|
55
|
+
* Document query filter.
|
|
56
|
+
* Uses Document for compatibility with MongoDB driver methods.
|
|
57
|
+
*/
|
|
58
|
+
export type DocumentQuery = Filter<Document>;
|
|
59
|
+
/**
|
|
60
|
+
* Document update specification
|
|
61
|
+
*/
|
|
62
|
+
export type DocumentUpdate = UpdateFilter<Document>;
|
|
63
|
+
/**
|
|
64
|
+
* How to interpret a string id when building an `_id` filter.
|
|
65
|
+
*
|
|
66
|
+
* - `"objectId"` — coerce to an ObjectId (falls back to the raw string when the
|
|
67
|
+
* value is not a valid ObjectId).
|
|
68
|
+
* - `"string"` — match the raw string `_id` only.
|
|
69
|
+
* - `"auto"` (default) — when the id is a valid ObjectId, match EITHER an
|
|
70
|
+
* ObjectId `_id` or the raw string `_id`, so documents stored with a
|
|
71
|
+
* string `_id` that happens to be 24-hex (e.g. MongoStorage keys) stay
|
|
72
|
+
* reachable. Otherwise match the string.
|
|
73
|
+
*/
|
|
74
|
+
export type IdType = "auto" | "objectId" | "string";
|
|
75
|
+
/**
|
|
76
|
+
* Build an `_id` filter from a string id.
|
|
77
|
+
*
|
|
78
|
+
* MongoDB supports any `_id` type at runtime. Previously any string that parsed
|
|
79
|
+
* as an ObjectId was silently coerced, making 24-hex *string* `_id`s
|
|
80
|
+
* unreachable. The default `"auto"` mode now queries both forms via `$or` when
|
|
81
|
+
* the id is ambiguous, and `idType` provides an explicit escape hatch.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildIdFilter(id: string, idType?: IdType): Document;
|
|
84
|
+
/**
|
|
85
|
+
* Base metadata for all procedures
|
|
86
|
+
*/
|
|
87
|
+
export interface BaseMeta extends Record<string, unknown> {
|
|
88
|
+
/** Override database name */
|
|
89
|
+
database?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Metadata for collection-scoped procedures
|
|
93
|
+
*/
|
|
94
|
+
export interface CollectionMeta extends BaseMeta {
|
|
95
|
+
/** Collection name (required) */
|
|
96
|
+
collection: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Type guard to check if metadata has collection
|
|
100
|
+
*/
|
|
101
|
+
export declare function hasCollection(metadata: Record<string, unknown>): metadata is CollectionMeta;
|
|
102
|
+
/**
|
|
103
|
+
* Type guard to get collection metadata, throws if missing
|
|
104
|
+
*/
|
|
105
|
+
export declare function requireCollection(metadata: Record<string, unknown>): CollectionMeta;
|
|
106
|
+
/**
|
|
107
|
+
* Get base metadata (database override).
|
|
108
|
+
* BaseMeta extends Record<string, unknown> so this is type-safe.
|
|
109
|
+
*/
|
|
110
|
+
export declare function getBaseMeta(metadata: Record<string, unknown>): BaseMeta;
|
|
111
|
+
/**
|
|
112
|
+
* Insert operation for bulk write
|
|
113
|
+
*/
|
|
114
|
+
export interface BulkInsertOne {
|
|
115
|
+
insertOne: {
|
|
116
|
+
document: Document;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Update operation for bulk write
|
|
121
|
+
*/
|
|
122
|
+
export interface BulkUpdateOne {
|
|
123
|
+
updateOne: {
|
|
124
|
+
filter: DocumentQuery;
|
|
125
|
+
update: DocumentUpdate;
|
|
126
|
+
upsert?: boolean;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Delete operation for bulk write
|
|
131
|
+
*/
|
|
132
|
+
export interface BulkDeleteOne {
|
|
133
|
+
deleteOne: {
|
|
134
|
+
filter: DocumentQuery;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Bulk operation union type
|
|
139
|
+
*/
|
|
140
|
+
export type BulkOperation = BulkInsertOne | BulkUpdateOne | BulkDeleteOne;
|
|
141
|
+
/**
|
|
142
|
+
* Result of a bulk write operation
|
|
143
|
+
*/
|
|
144
|
+
export interface BulkWriteResult {
|
|
145
|
+
acknowledged: boolean;
|
|
146
|
+
insertedCount: number;
|
|
147
|
+
matchedCount: number;
|
|
148
|
+
modifiedCount: number;
|
|
149
|
+
deletedCount: number;
|
|
150
|
+
upsertedCount: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Index key specification
|
|
154
|
+
*/
|
|
155
|
+
export type IndexSpec = Record<string, 1 | -1 | "text" | "2dsphere">;
|
|
156
|
+
/**
|
|
157
|
+
* Index creation options
|
|
158
|
+
*/
|
|
159
|
+
export interface IndexOptions {
|
|
160
|
+
/** Index name */
|
|
161
|
+
name?: string | undefined;
|
|
162
|
+
/** Unique index */
|
|
163
|
+
unique?: boolean | undefined;
|
|
164
|
+
/** Sparse index */
|
|
165
|
+
sparse?: boolean | undefined;
|
|
166
|
+
/** Build in background */
|
|
167
|
+
background?: boolean | undefined;
|
|
168
|
+
/** TTL in seconds */
|
|
169
|
+
expireAfterSeconds?: number | undefined;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Index information returned by listIndexes
|
|
173
|
+
*/
|
|
174
|
+
export interface IndexInfo {
|
|
175
|
+
name: string;
|
|
176
|
+
/** The fields of the index and their kind. The server also gives kinds that IndexSpec does not name ("hashed", "2d"). */
|
|
177
|
+
key: Record<string, number | string>;
|
|
178
|
+
unique?: boolean | undefined;
|
|
179
|
+
sparse?: boolean | undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Collection creation options
|
|
183
|
+
*/
|
|
184
|
+
export interface CollectionOptions {
|
|
185
|
+
/** Create a capped collection */
|
|
186
|
+
capped?: boolean | undefined;
|
|
187
|
+
/** Max size in bytes (for capped) */
|
|
188
|
+
size?: number | undefined;
|
|
189
|
+
/** Max documents (for capped) */
|
|
190
|
+
max?: number | undefined;
|
|
191
|
+
/** JSON Schema validator */
|
|
192
|
+
validator?: Document | undefined;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Collection statistics
|
|
196
|
+
*/
|
|
197
|
+
export interface CollectionStats {
|
|
198
|
+
/** Number of documents */
|
|
199
|
+
count: number;
|
|
200
|
+
/** Size of documents in bytes */
|
|
201
|
+
size: number;
|
|
202
|
+
/** Average document size */
|
|
203
|
+
avgObjSize: number;
|
|
204
|
+
/** Total storage size */
|
|
205
|
+
storageSize: number;
|
|
206
|
+
/** Number of indexes */
|
|
207
|
+
nindexes: number;
|
|
208
|
+
/** Total index size */
|
|
209
|
+
totalIndexSize: number;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Database information
|
|
213
|
+
*/
|
|
214
|
+
export interface DatabaseInfo {
|
|
215
|
+
/** Database name */
|
|
216
|
+
name: string;
|
|
217
|
+
/** Number of collections */
|
|
218
|
+
collections: number;
|
|
219
|
+
/** Number of views */
|
|
220
|
+
views: number;
|
|
221
|
+
/** Size on disk in bytes */
|
|
222
|
+
sizeOnDisk: number;
|
|
223
|
+
/** Whether database is empty */
|
|
224
|
+
empty: boolean;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Aggregation pipeline stage
|
|
228
|
+
*/
|
|
229
|
+
export type AggregationStage = Document;
|
|
230
|
+
/**
|
|
231
|
+
* Aggregation options
|
|
232
|
+
*/
|
|
233
|
+
export interface AggregationOptions {
|
|
234
|
+
/** Allow disk use for large operations */
|
|
235
|
+
allowDiskUse?: boolean | undefined;
|
|
236
|
+
/** Max execution time in ms */
|
|
237
|
+
maxTimeMS?: number | undefined;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for client-mongo procedures
|
|
3
|
+
*/
|
|
4
|
+
import { ObjectId } from "mongodb";
|
|
5
|
+
/**
|
|
6
|
+
* Build an `_id` filter from a string id.
|
|
7
|
+
*
|
|
8
|
+
* MongoDB supports any `_id` type at runtime. Previously any string that parsed
|
|
9
|
+
* as an ObjectId was silently coerced, making 24-hex *string* `_id`s
|
|
10
|
+
* unreachable. The default `"auto"` mode now queries both forms via `$or` when
|
|
11
|
+
* the id is ambiguous, and `idType` provides an explicit escape hatch.
|
|
12
|
+
*/
|
|
13
|
+
export function buildIdFilter(id, idType = "auto") {
|
|
14
|
+
if (idType === "string") {
|
|
15
|
+
return { _id: id };
|
|
16
|
+
}
|
|
17
|
+
let objectId = null;
|
|
18
|
+
try {
|
|
19
|
+
objectId = new ObjectId(id);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
objectId = null;
|
|
23
|
+
}
|
|
24
|
+
if (idType === "objectId") {
|
|
25
|
+
return { _id: objectId ?? id };
|
|
26
|
+
}
|
|
27
|
+
// "auto": match both the ObjectId and the raw string when ambiguous.
|
|
28
|
+
if (objectId) {
|
|
29
|
+
return { $or: [{ _id: objectId }, { _id: id }] };
|
|
30
|
+
}
|
|
31
|
+
return { _id: id };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Type guard to check if metadata has collection
|
|
35
|
+
*/
|
|
36
|
+
export function hasCollection(metadata) {
|
|
37
|
+
return typeof metadata["collection"] === "string";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Type guard to get collection metadata, throws if missing
|
|
41
|
+
*/
|
|
42
|
+
export function requireCollection(metadata) {
|
|
43
|
+
if (!hasCollection(metadata)) {
|
|
44
|
+
throw new Error("collection is required in metadata");
|
|
45
|
+
}
|
|
46
|
+
if (metadata.collection.trim().length === 0) {
|
|
47
|
+
throw new Error("collection must be a non-empty string");
|
|
48
|
+
}
|
|
49
|
+
return metadata;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get base metadata (database override).
|
|
53
|
+
* BaseMeta extends Record<string, unknown> so this is type-safe.
|
|
54
|
+
*/
|
|
55
|
+
export function getBaseMeta(metadata) {
|
|
56
|
+
return metadata;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA0FnC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAAU,EAAE,MAAM,GAAW,MAAM;IAC/D,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,GAAoB,IAAI,CAAC;IACrC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,qEAAqE;IACrE,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACrB,CAAC;AAsBD;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAiC;IAEjC,OAAO,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAiC;IAEjC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,QAAiC;IAC3D,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,87 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@procedures/mongo",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "MongoDB as typed procedures: documents, collections, indexes, aggregation and database info, with a lazy connection and safe update and delete targets.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"mongodb",
|
|
8
|
+
"mongo",
|
|
9
|
+
"database",
|
|
10
|
+
"crud",
|
|
11
|
+
"aggregation",
|
|
12
|
+
"procedures",
|
|
13
|
+
"rpc"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://mark1russell7.github.io/client/",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/mark1russell7/client/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/mark1russell7/client.git",
|
|
22
|
+
"directory": "packages/client-mongo"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "Mark Russell (https://github.com/mark1russell7)",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./module": {
|
|
35
|
+
"types": "./dist/module.d.ts",
|
|
36
|
+
"import": "./dist/module.js"
|
|
37
|
+
},
|
|
38
|
+
"./procedures": {
|
|
39
|
+
"types": "./dist/procedures/index.d.ts",
|
|
40
|
+
"import": "./dist/procedures/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./register": {
|
|
43
|
+
"types": "./dist/register.d.ts",
|
|
44
|
+
"import": "./dist/register.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"src",
|
|
50
|
+
"!src/**/*.test.ts",
|
|
51
|
+
"!src/**/*.test.tsx",
|
|
52
|
+
"!src/**/__tests__",
|
|
53
|
+
"CHANGELOG.md"
|
|
54
|
+
],
|
|
55
|
+
"sideEffects": [
|
|
56
|
+
"./dist/register.js"
|
|
57
|
+
],
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=22"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public",
|
|
63
|
+
"provenance": true
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@mark1russell7/cue": "^1.0.0",
|
|
67
|
+
"@types/node": "^22.0.0",
|
|
68
|
+
"typescript": "^7.0.2",
|
|
69
|
+
"vitest": "^5.0.3"
|
|
70
|
+
},
|
|
71
|
+
"client": {
|
|
72
|
+
"procedures": "./dist/register.js"
|
|
73
|
+
},
|
|
74
|
+
"dependencies": {
|
|
75
|
+
"@procedures/client": "0.2.0",
|
|
76
|
+
"@procedures/collections": "0.2.0",
|
|
77
|
+
"mongodb": "^7.0.0",
|
|
78
|
+
"zod": "^4.6.5"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "tsc -b",
|
|
82
|
+
"typecheck": "tsc --noEmit",
|
|
83
|
+
"clean": "rm -rf dist .tsbuildinfo",
|
|
84
|
+
"test": "vitest run",
|
|
85
|
+
"test:watch": "vitest"
|
|
86
|
+
}
|
|
6
87
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MongoDB connection management for client-mongo
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Environment variable configuration (MONGODB_URI, MONGODB_DATABASE)
|
|
6
|
+
* - Programmatic configuration
|
|
7
|
+
* - Singleton pattern for default connection
|
|
8
|
+
* - Multiple connections for multi-tenant scenarios
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { MongoClient, Db, type MongoClientOptions } from "mongodb";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Options for creating a MongoDB connection
|
|
15
|
+
*/
|
|
16
|
+
export interface MongoConnectionOptions {
|
|
17
|
+
/** MongoDB connection URI (default: MONGODB_URI env var or mongodb://localhost:27017) */
|
|
18
|
+
uri?: string;
|
|
19
|
+
/** Database name (default: MONGODB_DATABASE env var or "test") */
|
|
20
|
+
database?: string;
|
|
21
|
+
/** Additional MongoDB client options */
|
|
22
|
+
clientOptions?: MongoClientOptions;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* MongoDB connection interface
|
|
27
|
+
*/
|
|
28
|
+
export interface MongoConnection {
|
|
29
|
+
/** Get the database instance */
|
|
30
|
+
getDb(): Db;
|
|
31
|
+
/** Get the underlying MongoClient */
|
|
32
|
+
getClient(): MongoClient;
|
|
33
|
+
/** Connect to the database (no-op if already connected) */
|
|
34
|
+
connect(): Promise<void>;
|
|
35
|
+
/** Disconnect from the database */
|
|
36
|
+
disconnect(): Promise<void>;
|
|
37
|
+
/** Check if connected */
|
|
38
|
+
isConnected(): boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Default connection singleton
|
|
42
|
+
let defaultConnection: MongoConnection | null = null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Set the default connection used by procedures
|
|
46
|
+
*/
|
|
47
|
+
export function setDefaultConnection(conn: MongoConnection): void {
|
|
48
|
+
defaultConnection = conn;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the default connection
|
|
53
|
+
* @throws Error if no connection has been established
|
|
54
|
+
*/
|
|
55
|
+
export function getDefaultConnection(): MongoConnection {
|
|
56
|
+
if (!defaultConnection) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"MongoDB connection not initialized. Call connect() first."
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return defaultConnection;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Check if a default connection exists
|
|
66
|
+
*/
|
|
67
|
+
export function hasDefaultConnection(): boolean {
|
|
68
|
+
return defaultConnection !== null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Create and connect to MongoDB
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* // Using environment variables
|
|
77
|
+
* await connect();
|
|
78
|
+
*
|
|
79
|
+
* // With explicit options
|
|
80
|
+
* await connect({
|
|
81
|
+
* uri: "mongodb://localhost:27017",
|
|
82
|
+
* database: "myapp"
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export async function connect(
|
|
87
|
+
options: MongoConnectionOptions = {}
|
|
88
|
+
): Promise<MongoConnection> {
|
|
89
|
+
const uri =
|
|
90
|
+
options.uri ?? process.env["MONGODB_URI"] ?? "mongodb://localhost:27017";
|
|
91
|
+
const database =
|
|
92
|
+
options.database ?? process.env["MONGODB_DATABASE"] ?? "test";
|
|
93
|
+
|
|
94
|
+
const client = new MongoClient(uri, options.clientOptions);
|
|
95
|
+
await client.connect();
|
|
96
|
+
|
|
97
|
+
// Close any previous default connection before replacing it. Without this,
|
|
98
|
+
// the prior MongoClient (and its connection pool) is orphaned open and leaks
|
|
99
|
+
// on every call to connect() (e.g. repeated server.mongo.start invocations).
|
|
100
|
+
const previousConnection = defaultConnection;
|
|
101
|
+
|
|
102
|
+
let connected = true;
|
|
103
|
+
|
|
104
|
+
const connection: MongoConnection = {
|
|
105
|
+
getDb: () => {
|
|
106
|
+
if (!connected) {
|
|
107
|
+
throw new Error("Connection has been closed");
|
|
108
|
+
}
|
|
109
|
+
return client.db(database);
|
|
110
|
+
},
|
|
111
|
+
getClient: () => {
|
|
112
|
+
if (!connected) {
|
|
113
|
+
throw new Error("Connection has been closed");
|
|
114
|
+
}
|
|
115
|
+
return client;
|
|
116
|
+
},
|
|
117
|
+
connect: async () => {
|
|
118
|
+
// Already connected
|
|
119
|
+
},
|
|
120
|
+
disconnect: async () => {
|
|
121
|
+
if (connected) {
|
|
122
|
+
await client.close();
|
|
123
|
+
connected = false;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
isConnected: () => connected,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
setDefaultConnection(connection);
|
|
130
|
+
|
|
131
|
+
if (previousConnection && previousConnection !== connection) {
|
|
132
|
+
try {
|
|
133
|
+
await previousConnection.disconnect();
|
|
134
|
+
} catch {
|
|
135
|
+
// Best effort: ignore errors closing the stale connection so a failure
|
|
136
|
+
// to close the old client never breaks establishing the new one.
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return connection;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// The options of the connection that ensureConnection() makes, and its attempt in progress
|
|
144
|
+
let lazyOptions: MongoConnectionOptions = {};
|
|
145
|
+
let pending: Promise<MongoConnection> | null = null;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Set the options of the connection that the procedures make on their first call.
|
|
149
|
+
* The defaults are the `MONGODB_URI` and `MONGODB_DATABASE` environment variables.
|
|
150
|
+
*/
|
|
151
|
+
export function configure(options: MongoConnectionOptions): void {
|
|
152
|
+
lazyOptions = options;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get the default connection, and connect first when there is no open one.
|
|
157
|
+
*
|
|
158
|
+
* The procedures call this function, so a host does not have to call `connect()`. (Before,
|
|
159
|
+
* nothing called `connect()`, and each `mongo.*` tool of the MCP server failed: deep dive DATA-5.)
|
|
160
|
+
* Concurrent first calls share one connection attempt.
|
|
161
|
+
*/
|
|
162
|
+
export function ensureConnection(): Promise<MongoConnection> {
|
|
163
|
+
if (defaultConnection?.isConnected()) {
|
|
164
|
+
return Promise.resolve(defaultConnection);
|
|
165
|
+
}
|
|
166
|
+
if (!pending) {
|
|
167
|
+
pending = connect(lazyOptions).finally(() => {
|
|
168
|
+
pending = null;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return pending;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Disconnect the default connection
|
|
176
|
+
*/
|
|
177
|
+
export async function disconnect(): Promise<void> {
|
|
178
|
+
if (defaultConnection) {
|
|
179
|
+
await defaultConnection.disconnect();
|
|
180
|
+
defaultConnection = null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the database from the default connection
|
|
186
|
+
* Convenience function for procedure handlers
|
|
187
|
+
*/
|
|
188
|
+
export function getDb(): Db {
|
|
189
|
+
return getDefaultConnection().getDb();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get the MongoClient from the default connection
|
|
194
|
+
* Convenience function for advanced operations
|
|
195
|
+
*/
|
|
196
|
+
export function getClient(): MongoClient {
|
|
197
|
+
return getDefaultConnection().getClient();
|
|
198
|
+
}
|