11/* eslint-disable @typescript-eslint/no-restricted-imports */
22import * as fs from 'node:fs' ;
33import * as path from 'node:path' ;
4+ import * as process from 'node:process' ;
5+ import * as vm from 'node:vm' ;
46
57// eslint-disable-next-line @typescript-eslint/no-unused-vars
68function printExports ( ) {
@@ -23,6 +25,75 @@ function printExports() {
2325 }
2426}
2527
28+ /**
29+ * Using node's require resolution logic this function will locate the entrypoint for the `'mongodb-legacy'` module,
30+ * then execute the `mongodb-legacy` module in a `vm` context that replaces the global require function with a custom
31+ * implementation. The custom version of `require` will return the local instance of the driver import (magically compiled by ts-node) when
32+ * the module specifier is 'mongodb' and otherwise defer to the normal require behavior to import relative files and stdlib modules.
33+ * Each of the legacy module's patched classes are placed on the input object.
34+ *
35+ * @param exportsToOverride - An object that is an import of the MongoDB driver to be modified by this function
36+ */
37+ function importMongoDBLegacy ( exportsToOverride : Record < string , unknown > ) {
38+ const mongodbLegacyEntryPoint = require . resolve ( 'mongodb-legacy' ) ;
39+ const mongodbLegacyLocation = path . dirname ( mongodbLegacyEntryPoint ) ;
40+ const mongodbLegacyIndex = fs . readFileSync ( mongodbLegacyEntryPoint , {
41+ encoding : 'utf8'
42+ } ) ;
43+ // eslint-disable-next-line @typescript-eslint/no-var-requires
44+ const localMongoDB = require ( '../src/index' ) ;
45+ const ctx = vm . createContext ( {
46+ module : { exports : null } ,
47+ require : ( mod : string ) => {
48+ if ( mod === 'mongodb' ) {
49+ return localMongoDB ;
50+ } else if ( mod . startsWith ( '.' ) ) {
51+ return require ( path . join ( mongodbLegacyLocation , mod ) ) ;
52+ }
53+ return require ( mod ) ;
54+ }
55+ } ) ;
56+ vm . runInContext ( mongodbLegacyIndex , ctx ) ;
57+
58+ const mongodbLegacy = ctx . module . exports ;
59+
60+ Object . defineProperty ( exportsToOverride , 'Admin' , { get : ( ) => mongodbLegacy . Admin } ) ;
61+ Object . defineProperty ( exportsToOverride , 'FindCursor' , { get : ( ) => mongodbLegacy . FindCursor } ) ;
62+ Object . defineProperty ( exportsToOverride , 'ListCollectionsCursor' , {
63+ get : ( ) => mongodbLegacy . ListCollectionsCursor
64+ } ) ;
65+ Object . defineProperty ( exportsToOverride , 'ListIndexesCursor' , {
66+ get : ( ) => mongodbLegacy . ListIndexesCursor
67+ } ) ;
68+ Object . defineProperty ( exportsToOverride , 'AggregationCursor' , {
69+ get : ( ) => mongodbLegacy . AggregationCursor
70+ } ) ;
71+ Object . defineProperty ( exportsToOverride , 'ChangeStream' , {
72+ get : ( ) => mongodbLegacy . ChangeStream
73+ } ) ;
74+ Object . defineProperty ( exportsToOverride , 'Collection' , { get : ( ) => mongodbLegacy . Collection } ) ;
75+ Object . defineProperty ( exportsToOverride , 'Db' , { get : ( ) => mongodbLegacy . Db } ) ;
76+ Object . defineProperty ( exportsToOverride , 'GridFSBucket' , {
77+ get : ( ) => mongodbLegacy . GridFSBucket
78+ } ) ;
79+ Object . defineProperty ( exportsToOverride , 'ClientSession' , {
80+ get : ( ) => mongodbLegacy . ClientSession
81+ } ) ;
82+ Object . defineProperty ( exportsToOverride , 'MongoClient' , { get : ( ) => mongodbLegacy . MongoClient } ) ;
83+ Object . defineProperty ( exportsToOverride , 'ClientSession' , {
84+ get : ( ) => mongodbLegacy . ClientSession
85+ } ) ;
86+ Object . defineProperty ( exportsToOverride , 'GridFSBucketWriteStream' , {
87+ get : ( ) => mongodbLegacy . GridFSBucketWriteStream
88+ } ) ;
89+ Object . defineProperty ( exportsToOverride , 'OrderedBulkOperation' , {
90+ get : ( ) => mongodbLegacy . OrderedBulkOperation
91+ } ) ;
92+ Object . defineProperty ( exportsToOverride , 'UnorderedBulkOperation' , {
93+ get : ( ) => mongodbLegacy . UnorderedBulkOperation
94+ } ) ;
95+ }
96+
2697export * from '../src/admin' ;
2798export * from '../src/bson' ;
2899export * from '../src/bulk/common' ;
@@ -125,3 +196,16 @@ export * from '../src/write_concern';
125196
126197// Must be last for precedence
127198export * from '../src/index' ;
199+
200+ /**
201+ * TODO(NODE-4979): ENABLE_MONGODB_LEGACY is 'true' by default for now
202+ */
203+ const ENABLE_MONGODB_LEGACY =
204+ typeof process . env . ENABLE_MONGODB_LEGACY === 'string' && process . env . ENABLE_MONGODB_LEGACY !== ''
205+ ? process . env . ENABLE_MONGODB_LEGACY
206+ : 'true' ;
207+
208+ if ( ENABLE_MONGODB_LEGACY === 'true' ) {
209+ // Override our own exports with the legacy patched ones
210+ importMongoDBLegacy ( module . exports ) ;
211+ }
0 commit comments