mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
refactor to typescript
This commit is contained in:
@@ -100,7 +100,7 @@ Package.onUse(function (api) {
|
||||
"server"
|
||||
);
|
||||
api.addFiles("local_collection_driver.js", ["client", "server"]);
|
||||
api.addFiles("remote_collection_driver.js", "server");
|
||||
api.addFiles("remote_collection_driver.ts", "server");
|
||||
api.addFiles("collection.js", ["client", "server"]);
|
||||
api.addFiles("connection_options.js", "server");
|
||||
api.addAssets("mongo.d.ts", "server");
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
import once from 'lodash.once';
|
||||
import {
|
||||
ASYNC_COLLECTION_METHODS,
|
||||
getAsyncMethodName,
|
||||
CLIENT_ONLY_METHODS
|
||||
} from "meteor/minimongo/constants";
|
||||
import { MongoConnection } from './mongo_connection';
|
||||
|
||||
MongoInternals.RemoteCollectionDriver = function (mongo_url, options) {
|
||||
this.mongo = new MongoConnection(mongo_url, options);
|
||||
};
|
||||
|
||||
const REMOTE_COLLECTION_METHODS = [
|
||||
'createCappedCollectionAsync',
|
||||
'dropIndexAsync',
|
||||
'ensureIndexAsync',
|
||||
'createIndexAsync',
|
||||
'countDocuments',
|
||||
'dropCollectionAsync',
|
||||
'estimatedDocumentCount',
|
||||
'find',
|
||||
'findOneAsync',
|
||||
'insertAsync',
|
||||
'rawCollection',
|
||||
'removeAsync',
|
||||
'updateAsync',
|
||||
'upsertAsync',
|
||||
];
|
||||
|
||||
Object.assign(MongoInternals.RemoteCollectionDriver.prototype, {
|
||||
open: function (name) {
|
||||
var self = this;
|
||||
var ret = {};
|
||||
|
||||
REMOTE_COLLECTION_METHODS.forEach(function (m) {
|
||||
ret[m] = self.mongo[m].bind(self.mongo, name);
|
||||
|
||||
if (!ASYNC_COLLECTION_METHODS.includes(m)) return;
|
||||
const asyncMethodName = getAsyncMethodName(m);
|
||||
ret[asyncMethodName] = function (...args) {
|
||||
return ret[m](...args);
|
||||
};
|
||||
});
|
||||
|
||||
CLIENT_ONLY_METHODS.forEach(function (m) {
|
||||
ret[m] = function (...args) {
|
||||
throw new Error(
|
||||
`${m} is not available on the server. Please use ${getAsyncMethodName(
|
||||
m
|
||||
)}() instead.`
|
||||
);
|
||||
};
|
||||
});
|
||||
return ret;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// Create the singleton RemoteCollectionDriver only on demand, so we
|
||||
// only require Mongo configuration if it's actually used (eg, not if
|
||||
// you're only trying to receive data from a remote DDP server.)
|
||||
MongoInternals.defaultRemoteCollectionDriver = once(function () {
|
||||
var connectionOptions = {};
|
||||
|
||||
var mongoUrl = process.env.MONGO_URL;
|
||||
|
||||
if (process.env.MONGO_OPLOG_URL) {
|
||||
connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL;
|
||||
}
|
||||
|
||||
if (! mongoUrl)
|
||||
throw new Error("MONGO_URL must be set in environment");
|
||||
|
||||
const driver = new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions);
|
||||
// As many deployment tools, including Meteor Up, send requests to the app in
|
||||
// order to confirm that the deployment finished successfully, it's required
|
||||
// to know about a database connection problem before the app starts. Doing so
|
||||
// in a `Meteor.startup` is fine, as the `WebApp` handles requests only after
|
||||
// all are finished.
|
||||
Meteor.startup(async () => {
|
||||
await driver.mongo.client.connect();
|
||||
});
|
||||
|
||||
return driver;
|
||||
});
|
||||
130
packages/mongo/remote_collection_driver.ts
Normal file
130
packages/mongo/remote_collection_driver.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import once from 'lodash.once';
|
||||
import {
|
||||
ASYNC_COLLECTION_METHODS,
|
||||
getAsyncMethodName,
|
||||
CLIENT_ONLY_METHODS
|
||||
} from "meteor/minimongo/constants";
|
||||
import { MongoConnection } from './mongo_connection';
|
||||
|
||||
// Define interfaces and types
|
||||
interface IConnectionOptions {
|
||||
oplogUrl?: string;
|
||||
[key: string]: unknown; // Changed from 'any' to 'unknown' for better type safety
|
||||
}
|
||||
|
||||
interface IMongoInternals {
|
||||
RemoteCollectionDriver: typeof RemoteCollectionDriver;
|
||||
defaultRemoteCollectionDriver: () => RemoteCollectionDriver;
|
||||
}
|
||||
|
||||
// More specific typing for collection methods
|
||||
type MongoMethodFunction = (...args: unknown[]) => unknown;
|
||||
interface ICollectionMethods {
|
||||
[key: string]: MongoMethodFunction;
|
||||
}
|
||||
|
||||
// Type for MongoConnection
|
||||
interface IMongoClient {
|
||||
connect: () => Promise<void>;
|
||||
}
|
||||
|
||||
interface IMongoConnection {
|
||||
client: IMongoClient;
|
||||
[key: string]: MongoMethodFunction | IMongoClient;
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
MONGO_URL: string;
|
||||
MONGO_OPLOG_URL?: string;
|
||||
}
|
||||
}
|
||||
|
||||
const MongoInternals: IMongoInternals;
|
||||
const Meteor: {
|
||||
startup: (callback: () => Promise<void>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
class RemoteCollectionDriver {
|
||||
private readonly mongo: MongoConnection;
|
||||
|
||||
private static readonly REMOTE_COLLECTION_METHODS = [
|
||||
'createCappedCollectionAsync',
|
||||
'dropIndexAsync',
|
||||
'ensureIndexAsync',
|
||||
'createIndexAsync',
|
||||
'countDocuments',
|
||||
'dropCollectionAsync',
|
||||
'estimatedDocumentCount',
|
||||
'find',
|
||||
'findOneAsync',
|
||||
'insertAsync',
|
||||
'rawCollection',
|
||||
'removeAsync',
|
||||
'updateAsync',
|
||||
'upsertAsync',
|
||||
] as const;
|
||||
|
||||
constructor(mongoUrl: string, options: IConnectionOptions) {
|
||||
this.mongo = new MongoConnection(mongoUrl, options);
|
||||
}
|
||||
|
||||
public open(name: string): ICollectionMethods {
|
||||
const ret: ICollectionMethods = {};
|
||||
|
||||
// Handle remote collection methods
|
||||
RemoteCollectionDriver.REMOTE_COLLECTION_METHODS.forEach((method) => {
|
||||
// Type assertion needed because we know these methods exist on MongoConnection
|
||||
const mongoMethod = this.mongo[method] as MongoMethodFunction;
|
||||
ret[method] = mongoMethod.bind(this.mongo, name);
|
||||
|
||||
if (!ASYNC_COLLECTION_METHODS.includes(method)) return;
|
||||
|
||||
const asyncMethodName = getAsyncMethodName(method);
|
||||
ret[asyncMethodName] = (...args: unknown[]) => ret[method](...args);
|
||||
});
|
||||
|
||||
// Handle client-only methods
|
||||
CLIENT_ONLY_METHODS.forEach((method) => {
|
||||
ret[method] = (...args: unknown[]): never => {
|
||||
throw new Error(
|
||||
`${method} is not available on the server. Please use ${getAsyncMethodName(
|
||||
method
|
||||
)}() instead.`
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the class to MongoInternals
|
||||
MongoInternals.RemoteCollectionDriver = RemoteCollectionDriver;
|
||||
|
||||
// Create the singleton RemoteCollectionDriver only on demand
|
||||
MongoInternals.defaultRemoteCollectionDriver = once((): RemoteCollectionDriver => {
|
||||
const connectionOptions: IConnectionOptions = {};
|
||||
const mongoUrl = process.env.MONGO_URL;
|
||||
|
||||
if (!mongoUrl) {
|
||||
throw new Error("MONGO_URL must be set in environment");
|
||||
}
|
||||
|
||||
if (process.env.MONGO_OPLOG_URL) {
|
||||
connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL;
|
||||
}
|
||||
|
||||
const driver = new RemoteCollectionDriver(mongoUrl, connectionOptions);
|
||||
|
||||
// Initialize database connection on startup
|
||||
Meteor.startup(async (): Promise<void> => {
|
||||
await driver.mongo.client.connect();
|
||||
});
|
||||
|
||||
return driver;
|
||||
});
|
||||
|
||||
export { RemoteCollectionDriver, IConnectionOptions, ICollectionMethods };
|
||||
Reference in New Issue
Block a user