@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.
Files changed (150) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1322 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/connection.d.ts +93 -0
  6. package/dist/connection.d.ts.map +1 -0
  7. package/dist/connection.js +147 -0
  8. package/dist/connection.js.map +1 -0
  9. package/dist/index.d.ts +34 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +45 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/module.d.ts +26 -0
  14. package/dist/module.d.ts.map +1 -0
  15. package/dist/module.js +66 -0
  16. package/dist/module.js.map +1 -0
  17. package/dist/procedures/collections.create.d.ts +21 -0
  18. package/dist/procedures/collections.create.d.ts.map +1 -0
  19. package/dist/procedures/collections.create.js +46 -0
  20. package/dist/procedures/collections.create.js.map +1 -0
  21. package/dist/procedures/collections.drop.d.ts +20 -0
  22. package/dist/procedures/collections.drop.d.ts.map +1 -0
  23. package/dist/procedures/collections.drop.js +40 -0
  24. package/dist/procedures/collections.drop.js.map +1 -0
  25. package/dist/procedures/collections.list.d.ts +17 -0
  26. package/dist/procedures/collections.list.d.ts.map +1 -0
  27. package/dist/procedures/collections.list.js +34 -0
  28. package/dist/procedures/collections.list.js.map +1 -0
  29. package/dist/procedures/collections.stats.d.ts +16 -0
  30. package/dist/procedures/collections.stats.d.ts.map +1 -0
  31. package/dist/procedures/collections.stats.js +41 -0
  32. package/dist/procedures/collections.stats.js.map +1 -0
  33. package/dist/procedures/database.info.d.ts +16 -0
  34. package/dist/procedures/database.info.d.ts.map +1 -0
  35. package/dist/procedures/database.info.js +41 -0
  36. package/dist/procedures/database.info.js.map +1 -0
  37. package/dist/procedures/database.ping.d.ts +18 -0
  38. package/dist/procedures/database.ping.d.ts.map +1 -0
  39. package/dist/procedures/database.ping.js +34 -0
  40. package/dist/procedures/database.ping.js.map +1 -0
  41. package/dist/procedures/documents.aggregate.d.ts +20 -0
  42. package/dist/procedures/documents.aggregate.d.ts.map +1 -0
  43. package/dist/procedures/documents.aggregate.js +43 -0
  44. package/dist/procedures/documents.aggregate.js.map +1 -0
  45. package/dist/procedures/documents.count.d.ts +19 -0
  46. package/dist/procedures/documents.count.d.ts.map +1 -0
  47. package/dist/procedures/documents.count.js +32 -0
  48. package/dist/procedures/documents.count.js.map +1 -0
  49. package/dist/procedures/documents.delete.d.ts +18 -0
  50. package/dist/procedures/documents.delete.d.ts.map +1 -0
  51. package/dist/procedures/documents.delete.js +34 -0
  52. package/dist/procedures/documents.delete.js.map +1 -0
  53. package/dist/procedures/documents.find.d.ts +24 -0
  54. package/dist/procedures/documents.find.d.ts.map +1 -0
  55. package/dist/procedures/documents.find.js +106 -0
  56. package/dist/procedures/documents.find.js.map +1 -0
  57. package/dist/procedures/documents.get.d.ts +21 -0
  58. package/dist/procedures/documents.get.d.ts.map +1 -0
  59. package/dist/procedures/documents.get.js +57 -0
  60. package/dist/procedures/documents.get.js.map +1 -0
  61. package/dist/procedures/documents.insert.d.ts +22 -0
  62. package/dist/procedures/documents.insert.d.ts.map +1 -0
  63. package/dist/procedures/documents.insert.js +58 -0
  64. package/dist/procedures/documents.insert.js.map +1 -0
  65. package/dist/procedures/documents.update.d.ts +27 -0
  66. package/dist/procedures/documents.update.d.ts.map +1 -0
  67. package/dist/procedures/documents.update.js +64 -0
  68. package/dist/procedures/documents.update.js.map +1 -0
  69. package/dist/procedures/index.d.ts +21 -0
  70. package/dist/procedures/index.d.ts.map +1 -0
  71. package/dist/procedures/index.js +26 -0
  72. package/dist/procedures/index.js.map +1 -0
  73. package/dist/procedures/indexes.create.d.ts +21 -0
  74. package/dist/procedures/indexes.create.d.ts.map +1 -0
  75. package/dist/procedures/indexes.create.js +48 -0
  76. package/dist/procedures/indexes.create.js.map +1 -0
  77. package/dist/procedures/indexes.drop.d.ts +18 -0
  78. package/dist/procedures/indexes.drop.d.ts.map +1 -0
  79. package/dist/procedures/indexes.drop.js +33 -0
  80. package/dist/procedures/indexes.drop.js.map +1 -0
  81. package/dist/procedures/indexes.list.d.ts +18 -0
  82. package/dist/procedures/indexes.list.d.ts.map +1 -0
  83. package/dist/procedures/indexes.list.js +43 -0
  84. package/dist/procedures/indexes.list.js.map +1 -0
  85. package/dist/procedures/input-schemas.d.ts +45 -0
  86. package/dist/procedures/input-schemas.d.ts.map +1 -0
  87. package/dist/procedures/input-schemas.js +52 -0
  88. package/dist/procedures/input-schemas.js.map +1 -0
  89. package/dist/procedures/schema.d.ts +2 -0
  90. package/dist/procedures/schema.d.ts.map +1 -0
  91. package/dist/procedures/schema.js +2 -0
  92. package/dist/procedures/schema.js.map +1 -0
  93. package/dist/procedures/target.d.ts +44 -0
  94. package/dist/procedures/target.d.ts.map +1 -0
  95. package/dist/procedures/target.js +98 -0
  96. package/dist/procedures/target.js.map +1 -0
  97. package/dist/procedures.types.d.ts +129 -0
  98. package/dist/procedures.types.d.ts.map +1 -0
  99. package/dist/procedures.types.js +24 -0
  100. package/dist/procedures.types.js.map +1 -0
  101. package/dist/register.d.ts +7 -0
  102. package/dist/register.d.ts.map +1 -0
  103. package/dist/register.js +9 -0
  104. package/dist/register.js.map +1 -0
  105. package/dist/scope.d.ts +33 -0
  106. package/dist/scope.d.ts.map +1 -0
  107. package/dist/scope.js +52 -0
  108. package/dist/scope.js.map +1 -0
  109. package/dist/storage/index.d.ts +6 -0
  110. package/dist/storage/index.d.ts.map +1 -0
  111. package/dist/storage/index.js +5 -0
  112. package/dist/storage/index.js.map +1 -0
  113. package/dist/storage/mongo-storage.d.ts +50 -0
  114. package/dist/storage/mongo-storage.d.ts.map +1 -0
  115. package/dist/storage/mongo-storage.js +109 -0
  116. package/dist/storage/mongo-storage.js.map +1 -0
  117. package/dist/types.d.ts +239 -0
  118. package/dist/types.d.ts.map +1 -0
  119. package/dist/types.js +58 -0
  120. package/dist/types.js.map +1 -0
  121. package/package.json +84 -3
  122. package/src/connection.ts +198 -0
  123. package/src/index.ts +159 -0
  124. package/src/module.ts +71 -0
  125. package/src/procedures/collections.create.ts +72 -0
  126. package/src/procedures/collections.drop.ts +66 -0
  127. package/src/procedures/collections.list.ts +56 -0
  128. package/src/procedures/collections.stats.ts +60 -0
  129. package/src/procedures/database.info.ts +61 -0
  130. package/src/procedures/database.ping.ts +57 -0
  131. package/src/procedures/documents.aggregate.ts +72 -0
  132. package/src/procedures/documents.count.ts +55 -0
  133. package/src/procedures/documents.delete.ts +57 -0
  134. package/src/procedures/documents.find.ts +151 -0
  135. package/src/procedures/documents.get.ts +102 -0
  136. package/src/procedures/documents.insert.ts +86 -0
  137. package/src/procedures/documents.update.ts +96 -0
  138. package/src/procedures/index.ts +30 -0
  139. package/src/procedures/indexes.create.ts +74 -0
  140. package/src/procedures/indexes.drop.ts +56 -0
  141. package/src/procedures/indexes.list.ts +67 -0
  142. package/src/procedures/input-schemas.ts +63 -0
  143. package/src/procedures/schema.ts +1 -0
  144. package/src/procedures/target.ts +123 -0
  145. package/src/procedures.types.ts +162 -0
  146. package/src/register.ts +11 -0
  147. package/src/scope.ts +69 -0
  148. package/src/storage/index.ts +6 -0
  149. package/src/storage/mongo-storage.ts +151 -0
  150. package/src/types.ts +337 -0
@@ -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.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
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
+ }