@rebasepro/server-mongodb 0.0.1-canary.09e5ec5
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/LICENSE +6 -0
- package/dist/ensure-collections-CNrcwVgY.js +74 -0
- package/dist/ensure-collections-CNrcwVgY.js.map +1 -0
- package/dist/ensure-history-collection-DBIiwmCm.js +15 -0
- package/dist/ensure-history-collection-DBIiwmCm.js.map +1 -0
- package/dist/index.es.js +1734 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +2043 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/server-core/src/api/ast-schema-editor.d.ts +22 -0
- package/dist/server-core/src/api/ast-schema-editor.d.ts.map +1 -0
- package/dist/server-core/src/api/errors.d.ts +36 -0
- package/dist/server-core/src/api/errors.d.ts.map +1 -0
- package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +36 -0
- package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts.map +1 -0
- package/dist/server-core/src/api/graphql/index.d.ts +2 -0
- package/dist/server-core/src/api/graphql/index.d.ts.map +1 -0
- package/dist/server-core/src/api/index.d.ts +10 -0
- package/dist/server-core/src/api/index.d.ts.map +1 -0
- package/dist/server-core/src/api/openapi-generator.d.ts +17 -0
- package/dist/server-core/src/api/openapi-generator.d.ts.map +1 -0
- package/dist/server-core/src/api/rest/api-generator.d.ts +65 -0
- package/dist/server-core/src/api/rest/api-generator.d.ts.map +1 -0
- package/dist/server-core/src/api/rest/index.d.ts +2 -0
- package/dist/server-core/src/api/rest/index.d.ts.map +1 -0
- package/dist/server-core/src/api/rest/query-parser.d.ts +10 -0
- package/dist/server-core/src/api/rest/query-parser.d.ts.map +1 -0
- package/dist/server-core/src/api/schema-editor-routes.d.ts +4 -0
- package/dist/server-core/src/api/schema-editor-routes.d.ts.map +1 -0
- package/dist/server-core/src/api/server.d.ts +41 -0
- package/dist/server-core/src/api/server.d.ts.map +1 -0
- package/dist/server-core/src/api/types.d.ts +91 -0
- package/dist/server-core/src/api/types.d.ts.map +1 -0
- package/dist/server-core/src/auth/admin-routes.d.ts +17 -0
- package/dist/server-core/src/auth/admin-routes.d.ts.map +1 -0
- package/dist/server-core/src/auth/apple-oauth.d.ts +31 -0
- package/dist/server-core/src/auth/apple-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/bitbucket-oauth.d.ts +12 -0
- package/dist/server-core/src/auth/bitbucket-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/discord-oauth.d.ts +15 -0
- package/dist/server-core/src/auth/discord-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/facebook-oauth.d.ts +15 -0
- package/dist/server-core/src/auth/facebook-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/github-oauth.d.ts +16 -0
- package/dist/server-core/src/auth/github-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/gitlab-oauth.d.ts +14 -0
- package/dist/server-core/src/auth/gitlab-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/google-oauth.d.ts +15 -0
- package/dist/server-core/src/auth/google-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/index.d.ts +24 -0
- package/dist/server-core/src/auth/index.d.ts.map +1 -0
- package/dist/server-core/src/auth/interfaces.d.ts +310 -0
- package/dist/server-core/src/auth/interfaces.d.ts.map +1 -0
- package/dist/server-core/src/auth/jwt.d.ts +44 -0
- package/dist/server-core/src/auth/jwt.d.ts.map +1 -0
- package/dist/server-core/src/auth/linkedin-oauth.d.ts +19 -0
- package/dist/server-core/src/auth/linkedin-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/microsoft-oauth.d.ts +17 -0
- package/dist/server-core/src/auth/microsoft-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/middleware.d.ts +82 -0
- package/dist/server-core/src/auth/middleware.d.ts.map +1 -0
- package/dist/server-core/src/auth/password.d.ts +23 -0
- package/dist/server-core/src/auth/password.d.ts.map +1 -0
- package/dist/server-core/src/auth/rate-limiter.d.ts +32 -0
- package/dist/server-core/src/auth/rate-limiter.d.ts.map +1 -0
- package/dist/server-core/src/auth/routes.d.ts +28 -0
- package/dist/server-core/src/auth/routes.d.ts.map +1 -0
- package/dist/server-core/src/auth/slack-oauth.d.ts +13 -0
- package/dist/server-core/src/auth/slack-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/spotify-oauth.d.ts +13 -0
- package/dist/server-core/src/auth/spotify-oauth.d.ts.map +1 -0
- package/dist/server-core/src/auth/twitter-oauth.d.ts +19 -0
- package/dist/server-core/src/auth/twitter-oauth.d.ts.map +1 -0
- package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +14 -0
- package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts.map +1 -0
- package/dist/server-core/src/collections/loader.d.ts +6 -0
- package/dist/server-core/src/collections/loader.d.ts.map +1 -0
- package/dist/server-core/src/cron/cron-loader.d.ts +18 -0
- package/dist/server-core/src/cron/cron-loader.d.ts.map +1 -0
- package/dist/server-core/src/cron/cron-routes.d.ts +15 -0
- package/dist/server-core/src/cron/cron-routes.d.ts.map +1 -0
- package/dist/server-core/src/cron/cron-scheduler.d.ts +62 -0
- package/dist/server-core/src/cron/cron-scheduler.d.ts.map +1 -0
- package/dist/server-core/src/cron/cron-store.d.ts +33 -0
- package/dist/server-core/src/cron/cron-store.d.ts.map +1 -0
- package/dist/server-core/src/cron/index.d.ts +7 -0
- package/dist/server-core/src/cron/index.d.ts.map +1 -0
- package/dist/server-core/src/db/interfaces.d.ts +19 -0
- package/dist/server-core/src/db/interfaces.d.ts.map +1 -0
- package/dist/server-core/src/email/index.d.ts +7 -0
- package/dist/server-core/src/email/index.d.ts.map +1 -0
- package/dist/server-core/src/email/smtp-email-service.d.ts +26 -0
- package/dist/server-core/src/email/smtp-email-service.d.ts.map +1 -0
- package/dist/server-core/src/email/templates.d.ts +43 -0
- package/dist/server-core/src/email/templates.d.ts.map +1 -0
- package/dist/server-core/src/email/types.d.ts +108 -0
- package/dist/server-core/src/email/types.d.ts.map +1 -0
- package/dist/server-core/src/functions/function-loader.d.ts +18 -0
- package/dist/server-core/src/functions/function-loader.d.ts.map +1 -0
- package/dist/server-core/src/functions/function-routes.d.ts +11 -0
- package/dist/server-core/src/functions/function-routes.d.ts.map +1 -0
- package/dist/server-core/src/functions/index.d.ts +4 -0
- package/dist/server-core/src/functions/index.d.ts.map +1 -0
- package/dist/server-core/src/history/history-routes.d.ts +24 -0
- package/dist/server-core/src/history/history-routes.d.ts.map +1 -0
- package/dist/server-core/src/history/index.d.ts +2 -0
- package/dist/server-core/src/history/index.d.ts.map +1 -0
- package/dist/server-core/src/index.d.ts +30 -0
- package/dist/server-core/src/index.d.ts.map +1 -0
- package/dist/server-core/src/init.d.ts +160 -0
- package/dist/server-core/src/init.d.ts.map +1 -0
- package/dist/server-core/src/serve-spa.d.ts +31 -0
- package/dist/server-core/src/serve-spa.d.ts.map +1 -0
- package/dist/server-core/src/services/driver-registry.d.ts +79 -0
- package/dist/server-core/src/services/driver-registry.d.ts.map +1 -0
- package/dist/server-core/src/singleton.d.ts +36 -0
- package/dist/server-core/src/singleton.d.ts.map +1 -0
- package/dist/server-core/src/storage/LocalStorageController.d.ts +47 -0
- package/dist/server-core/src/storage/LocalStorageController.d.ts.map +1 -0
- package/dist/server-core/src/storage/S3StorageController.d.ts +37 -0
- package/dist/server-core/src/storage/S3StorageController.d.ts.map +1 -0
- package/dist/server-core/src/storage/index.d.ts +26 -0
- package/dist/server-core/src/storage/index.d.ts.map +1 -0
- package/dist/server-core/src/storage/routes.d.ts +39 -0
- package/dist/server-core/src/storage/routes.d.ts.map +1 -0
- package/dist/server-core/src/storage/storage-registry.d.ts +79 -0
- package/dist/server-core/src/storage/storage-registry.d.ts.map +1 -0
- package/dist/server-core/src/storage/types.d.ts +104 -0
- package/dist/server-core/src/storage/types.d.ts.map +1 -0
- package/dist/server-core/src/types/index.d.ts +12 -0
- package/dist/server-core/src/types/index.d.ts.map +1 -0
- package/dist/server-core/src/utils/dev-port.d.ts +36 -0
- package/dist/server-core/src/utils/dev-port.d.ts.map +1 -0
- package/dist/server-core/src/utils/logger.d.ts +32 -0
- package/dist/server-core/src/utils/logger.d.ts.map +1 -0
- package/dist/server-core/src/utils/logging.d.ts +10 -0
- package/dist/server-core/src/utils/logging.d.ts.map +1 -0
- package/dist/server-core/src/utils/request-logger.d.ts +20 -0
- package/dist/server-core/src/utils/request-logger.d.ts.map +1 -0
- package/dist/server-core/src/utils/sql.d.ts +28 -0
- package/dist/server-core/src/utils/sql.d.ts.map +1 -0
- package/dist/server-mongodb/src/MongoBootstrapper.d.ts +18 -0
- package/dist/server-mongodb/src/MongoBootstrapper.d.ts.map +1 -0
- package/dist/server-mongodb/src/auth/ensure-collections.d.ts +3 -0
- package/dist/server-mongodb/src/auth/ensure-collections.d.ts.map +1 -0
- package/dist/server-mongodb/src/auth/services.d.ts +135 -0
- package/dist/server-mongodb/src/auth/services.d.ts.map +1 -0
- package/dist/server-mongodb/src/connection.d.ts +35 -0
- package/dist/server-mongodb/src/connection.d.ts.map +1 -0
- package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts +64 -0
- package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts.map +1 -0
- package/dist/server-mongodb/src/db/MongoEntityService.d.ts +98 -0
- package/dist/server-mongodb/src/db/MongoEntityService.d.ts.map +1 -0
- package/dist/server-mongodb/src/factory.d.ts +142 -0
- package/dist/server-mongodb/src/factory.d.ts.map +1 -0
- package/dist/server-mongodb/src/history/ensure-history-collection.d.ts +3 -0
- package/dist/server-mongodb/src/history/ensure-history-collection.d.ts.map +1 -0
- package/dist/server-mongodb/src/index.d.ts +18 -0
- package/dist/server-mongodb/src/index.d.ts.map +1 -0
- package/dist/server-mongodb/src/services/MongoDriver.d.ts +83 -0
- package/dist/server-mongodb/src/services/MongoDriver.d.ts.map +1 -0
- package/dist/server-mongodb/src/services/MongoHistoryService.d.ts +37 -0
- package/dist/server-mongodb/src/services/MongoHistoryService.d.ts.map +1 -0
- package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts +86 -0
- package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts.map +1 -0
- package/dist/server-mongodb/src/useMongoDriver.d.ts +18 -0
- package/dist/server-mongodb/src/useMongoDriver.d.ts.map +1 -0
- package/dist/server-mongodb/src/utils.d.ts +10 -0
- package/dist/server-mongodb/src/utils.d.ts.map +1 -0
- package/dist/server-mongodb/src/websocket.d.ts +7 -0
- package/dist/server-mongodb/src/websocket.d.ts.map +1 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +8 -0
- package/dist/types/src/controllers/analytics_controller.d.ts.map +1 -0
- package/dist/types/src/controllers/auth.d.ts +120 -0
- package/dist/types/src/controllers/auth.d.ts.map +1 -0
- package/dist/types/src/controllers/client.d.ts +171 -0
- package/dist/types/src/controllers/client.d.ts.map +1 -0
- package/dist/types/src/controllers/collection_registry.d.ts +46 -0
- package/dist/types/src/controllers/collection_registry.d.ts.map +1 -0
- package/dist/types/src/controllers/customization_controller.d.ts +61 -0
- package/dist/types/src/controllers/customization_controller.d.ts.map +1 -0
- package/dist/types/src/controllers/data.d.ts +169 -0
- package/dist/types/src/controllers/data.d.ts.map +1 -0
- package/dist/types/src/controllers/data_driver.d.ts +161 -0
- package/dist/types/src/controllers/data_driver.d.ts.map +1 -0
- package/dist/types/src/controllers/database_admin.d.ts +12 -0
- package/dist/types/src/controllers/database_admin.d.ts.map +1 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +37 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts.map +1 -0
- package/dist/types/src/controllers/effective_role.d.ts +5 -0
- package/dist/types/src/controllers/effective_role.d.ts.map +1 -0
- package/dist/types/src/controllers/email.d.ts +35 -0
- package/dist/types/src/controllers/email.d.ts.map +1 -0
- package/dist/types/src/controllers/index.d.ts +19 -0
- package/dist/types/src/controllers/index.d.ts.map +1 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +21 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts.map +1 -0
- package/dist/types/src/controllers/navigation.d.ts +214 -0
- package/dist/types/src/controllers/navigation.d.ts.map +1 -0
- package/dist/types/src/controllers/registry.d.ts +55 -0
- package/dist/types/src/controllers/registry.d.ts.map +1 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +68 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts.map +1 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +91 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts.map +1 -0
- package/dist/types/src/controllers/snackbar.d.ts +25 -0
- package/dist/types/src/controllers/snackbar.d.ts.map +1 -0
- package/dist/types/src/controllers/storage.d.ts +172 -0
- package/dist/types/src/controllers/storage.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/rebase_context.d.ts +106 -0
- package/dist/types/src/rebase_context.d.ts.map +1 -0
- package/dist/types/src/types/backend.d.ts +537 -0
- package/dist/types/src/types/backend.d.ts.map +1 -0
- package/dist/types/src/types/builders.d.ts +16 -0
- package/dist/types/src/types/builders.d.ts.map +1 -0
- package/dist/types/src/types/chips.d.ts +6 -0
- package/dist/types/src/types/chips.d.ts.map +1 -0
- package/dist/types/src/types/collections.d.ts +857 -0
- package/dist/types/src/types/collections.d.ts.map +1 -0
- package/dist/types/src/types/cron.d.ts +103 -0
- package/dist/types/src/types/cron.d.ts.map +1 -0
- package/dist/types/src/types/data_source.d.ts +65 -0
- package/dist/types/src/types/data_source.d.ts.map +1 -0
- package/dist/types/src/types/entities.d.ts +146 -0
- package/dist/types/src/types/entities.d.ts.map +1 -0
- package/dist/types/src/types/entity_actions.d.ts +99 -0
- package/dist/types/src/types/entity_actions.d.ts.map +1 -0
- package/dist/types/src/types/entity_callbacks.d.ts +174 -0
- package/dist/types/src/types/entity_callbacks.d.ts.map +1 -0
- package/dist/types/src/types/entity_link_builder.d.ts +8 -0
- package/dist/types/src/types/entity_link_builder.d.ts.map +1 -0
- package/dist/types/src/types/entity_overrides.d.ts +11 -0
- package/dist/types/src/types/entity_overrides.d.ts.map +1 -0
- package/dist/types/src/types/entity_views.d.ts +62 -0
- package/dist/types/src/types/entity_views.d.ts.map +1 -0
- package/dist/types/src/types/export_import.d.ts +22 -0
- package/dist/types/src/types/export_import.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +24 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/locales.d.ts +5 -0
- package/dist/types/src/types/locales.d.ts.map +1 -0
- package/dist/types/src/types/modify_collections.d.ts +6 -0
- package/dist/types/src/types/modify_collections.d.ts.map +1 -0
- package/dist/types/src/types/plugins.d.ts +280 -0
- package/dist/types/src/types/plugins.d.ts.map +1 -0
- package/dist/types/src/types/properties.d.ts +1177 -0
- package/dist/types/src/types/properties.d.ts.map +1 -0
- package/dist/types/src/types/property_config.d.ts +71 -0
- package/dist/types/src/types/property_config.d.ts.map +1 -0
- package/dist/types/src/types/relations.d.ts +337 -0
- package/dist/types/src/types/relations.d.ts.map +1 -0
- package/dist/types/src/types/slots.d.ts +253 -0
- package/dist/types/src/types/slots.d.ts.map +1 -0
- package/dist/types/src/types/translations.d.ts +871 -0
- package/dist/types/src/types/translations.d.ts.map +1 -0
- package/dist/types/src/types/user_management_delegate.d.ts +122 -0
- package/dist/types/src/types/user_management_delegate.d.ts.map +1 -0
- package/dist/types/src/types/websockets.d.ts +79 -0
- package/dist/types/src/types/websockets.d.ts.map +1 -0
- package/dist/types/src/users/index.d.ts +3 -0
- package/dist/types/src/users/index.d.ts.map +1 -0
- package/dist/types/src/users/roles.d.ts +23 -0
- package/dist/types/src/users/roles.d.ts.map +1 -0
- package/dist/types/src/users/user.d.ts +47 -0
- package/dist/types/src/users/user.d.ts.map +1 -0
- package/dist/websocket-BZlPuJrt.js +220 -0
- package/dist/websocket-BZlPuJrt.js.map +1 -0
- package/package.json +79 -0
- package/src/MongoBootstrapper.ts +177 -0
- package/src/auth/ensure-collections.ts +94 -0
- package/src/auth/services.ts +638 -0
- package/src/connection.ts +60 -0
- package/src/db/MongoConditionBuilder.ts +181 -0
- package/src/db/MongoEntityService.ts +350 -0
- package/src/factory.ts +289 -0
- package/src/history/ensure-history-collection.ts +19 -0
- package/src/index.ts +25 -0
- package/src/services/MongoDriver.ts +297 -0
- package/src/services/MongoDriver.ts.backup +266 -0
- package/src/services/MongoHistoryService.ts +154 -0
- package/src/services/MongoRealtimeService.ts +394 -0
- package/src/useMongoDriver.ts +519 -0
- package/src/utils.ts +28 -0
- package/src/websocket.ts +257 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/connection.ts","../src/db/MongoConditionBuilder.ts","../src/db/MongoEntityService.ts","../src/services/MongoRealtimeService.ts","../src/services/MongoHistoryService.ts","../src/services/MongoDriver.ts","../src/factory.ts","../src/auth/services.ts","../src/MongoBootstrapper.ts"],"sourcesContent":["/**\n * MongoDB Connection\n *\n * Wraps MongoDB connection to implement the DatabaseConnection interface.\n */\n\nimport { Db, MongoClient } from \"mongodb\";\nimport { DatabaseConnection } from \"@rebasepro/types\";\n\n/**\n * MongoDB database connection wrapper that implements DatabaseConnection interface.\n */\nexport class MongoDBConnection implements DatabaseConnection {\n readonly type = \"mongodb\";\n\n constructor(\n public readonly db: Db,\n public readonly client: MongoClient\n ) { }\n\n get isConnected(): boolean {\n // MongoClient doesn't have a direct isConnected property in v6+\n // We check if the client topology is connected\n try {\n const clientInternal = this.client as unknown as Record<string, { isConnected?: () => boolean } | undefined>;\n return clientInternal.topology?.isConnected?.() ?? false;\n } catch {\n return false;\n }\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n}\n\n/**\n * Create a MongoDB database connection from a connection string.\n *\n * @param connectionString - MongoDB connection string (e.g., mongodb://localhost:27017)\n * @param databaseName - Name of the database to use\n * @returns Promise resolving to MongoDBConnection\n *\n * @example\n * ```typescript\n * const connection = await createMongoDBConnection(\n * \"mongodb://localhost:27017\",\n * \"my_database\"\n * );\n * ```\n */\nexport async function createMongoDBConnection(\n connectionString: string,\n databaseName: string\n): Promise<MongoDBConnection> {\n const client = new MongoClient(connectionString);\n await client.connect();\n const db = client.db(databaseName);\n return new MongoDBConnection(db, client);\n}\n","/**\n * MongoDB Condition Builder\n *\n * Translates Rebase filter conditions to MongoDB query operators.\n */\n\nimport { FilterValues, WhereFilterOp } from \"@rebasepro/types\";\nimport { Filter, Document } from \"mongodb\";\n\n/**\n * Mapping from Rebase filter operators to MongoDB query operators\n */\nconst REBASE_TO_MONGO_OP: Record<WhereFilterOp, string> = {\n \"<\": \"$lt\",\n \"<=\": \"$lte\",\n \"==\": \"$eq\",\n \"!=\": \"$ne\",\n \">=\": \"$gte\",\n \">\": \"$gt\",\n \"array-contains\": \"$elemMatch\",\n \"array-contains-any\": \"$in\",\n \"in\": \"$in\",\n \"not-in\": \"$nin\"\n};\n\n/**\n * MongoDB Condition Builder\n *\n * Provides static methods to translate Rebase filter conditions\n * to MongoDB query filters.\n */\nexport class MongoConditionBuilder {\n /**\n * Build MongoDB filter conditions from Rebase FilterValues\n *\n * @param filter - Rebase filter values\n * @returns Array of MongoDB filter objects\n */\n static buildFilterConditions<M extends Record<string, any>>(\n filter: FilterValues<Extract<keyof M, string>>\n ): Filter<Document>[] {\n if (!filter) return [];\n\n const conditions: Filter<Document>[] = [];\n\n for (const [field, filterParam] of Object.entries(filter)) {\n if (!filterParam) continue;\n\n const [op, value] = filterParam as [WhereFilterOp, any];\n const mongoOp = REBASE_TO_MONGO_OP[op];\n\n if (!mongoOp) {\n console.warn(`Unsupported filter operator: ${op}`);\n continue;\n }\n\n // Handle array-contains specially\n if (op === \"array-contains\") {\n conditions.push({\n [field]: { $elemMatch: { $eq: value } }\n });\n } else {\n conditions.push({\n [field]: { [mongoOp]: value }\n });\n }\n }\n\n return conditions;\n }\n\n /**\n * Build search conditions for text search\n *\n * @param searchString - Text to search for\n * @param properties - Properties to search in\n * @returns Array of MongoDB filter objects for text search\n */\n static buildSearchConditions(\n searchString: string,\n properties: Record<string, any>\n ): Filter<Document>[] {\n if (!searchString) return [];\n\n // Build regex conditions for each searchable string property\n const orConditions: Filter<Document>[] = [];\n const searchRegex = new RegExp(searchString, \"i\");\n\n for (const [key, prop] of Object.entries(properties)) {\n // Only search in string-type properties\n if (prop?.dataType === \"string\" || typeof prop === \"string\") {\n orConditions.push({\n [key]: { $regex: searchRegex }\n });\n }\n }\n\n // If no properties to search, use MongoDB text search\n if (orConditions.length === 0) {\n return [{ $text: { $search: searchString } }];\n }\n\n return orConditions;\n }\n\n /**\n * Combine multiple conditions with AND operator\n *\n * @param conditions - Array of filter conditions\n * @returns Combined filter or undefined if empty\n */\n static combineConditionsWithAnd(conditions: Filter<Document>[]): Filter<Document> | undefined {\n if (conditions.length === 0) return undefined;\n if (conditions.length === 1) return conditions[0];\n return { $and: conditions };\n }\n\n /**\n * Combine multiple conditions with OR operator\n *\n * @param conditions - Array of filter conditions\n * @returns Combined filter or undefined if empty\n */\n static combineConditionsWithOr(conditions: Filter<Document>[]): Filter<Document> | undefined {\n if (conditions.length === 0) return undefined;\n if (conditions.length === 1) return conditions[0];\n return { $or: conditions };\n }\n\n /**\n * Build a complete MongoDB query from Rebase options\n *\n * @param options - Rebase fetch options\n * @returns MongoDB filter object\n */\n static buildQuery<M extends Record<string, any>>(options: {\n filter?: FilterValues<Extract<keyof M, string>>;\n searchString?: string;\n properties?: Record<string, any>;\n }): Filter<Document> {\n const conditions: Filter<Document>[] = [];\n\n // Add filter conditions\n if (options.filter) {\n const filterConditions = this.buildFilterConditions<M>(options.filter);\n conditions.push(...filterConditions);\n }\n\n // Add search conditions\n if (options.searchString && options.properties) {\n const searchConditions = this.buildSearchConditions(\n options.searchString,\n options.properties\n );\n if (searchConditions.length > 0) {\n // Search conditions are OR'd together\n const searchFilter = this.combineConditionsWithOr(searchConditions);\n if (searchFilter) {\n conditions.push(searchFilter);\n }\n }\n }\n\n return this.combineConditionsWithAnd(conditions) ?? {};\n }\n\n /**\n * Build MongoDB sort options from Rebase options\n *\n * @param orderBy - Field to order by\n * @param order - Sort direction\n * @returns MongoDB sort object\n */\n static buildSort(\n orderBy?: string,\n order?: \"asc\" | \"desc\"\n ): Record<string, 1 | -1> | undefined {\n if (!orderBy) return undefined;\n return { [orderBy]: order === \"desc\" ? -1 : 1 };\n }\n}\n","/**\n * MongoDB Entity Service\n *\n * Implements EntityRepository interface for MongoDB.\n * Provides all CRUD operations for entities.\n */\n\nimport { Db, ObjectId, Collection, Document, FindOptions, Filter } from \"mongodb\";\nimport { Entity, FilterValues, EntityRepository, EntityCollection } from \"@rebasepro/types\";\nimport { MongoConditionBuilder } from \"./MongoConditionBuilder\";\n\n/**\n * MongoDB Entity Service\n *\n * Implements the EntityRepository interface for MongoDB.\n * Provides all CRUD operations for entities stored in MongoDB collections.\n */\nexport class MongoEntityService implements EntityRepository {\n constructor(private db: Db) { }\n\n /**\n * Get a MongoDB collection by its path\n */\n private getCollection(collectionPath: string): Collection<Document> {\n // Handle nested paths (e.g., \"posts/123/comments\" -> \"posts_123_comments\")\n const collectionName = collectionPath.replace(/\\//g, \"_\");\n return this.db.collection(collectionName);\n }\n\n /**\n * Convert a string ID to ObjectId if it's a valid ObjectId string\n */\n private toObjectId(id: string | number): ObjectId | string | number {\n if (typeof id === \"string\" && ObjectId.isValid(id) && id.length === 24) {\n return new ObjectId(id);\n }\n return id;\n }\n\n /**\n * Convert a MongoDB document to a Rebase Entity\n */\n private documentToEntity<M extends Record<string, any>>(\n doc: Document,\n path: string\n ): Entity<M> {\n const { _id, ...values } = doc;\n return {\n id: _id.toString(),\n path,\n values: this.convertFromMongoValues(values) as M\n };\n }\n\n /**\n * Convert values from MongoDB format to Rebase format\n */\n private convertFromMongoValues(values: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(values)) {\n result[key] = this.convertFromMongoValue(value);\n }\n\n return result;\n }\n\n /**\n * Convert a single value from MongoDB format\n */\n private convertFromMongoValue(value: any): any {\n if (value === null || value === undefined) return value;\n\n // Handle ObjectId\n if (value instanceof ObjectId) {\n return value.toString();\n }\n\n // Handle Date\n if (value instanceof Date) {\n return value;\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n return value.map(v => this.convertFromMongoValue(v));\n }\n\n // Handle EntityReference-like objects\n if (typeof value === \"object\" && \"path\" in value && \"id\" in value) {\n return {\n path: value.path,\n id: value.id instanceof ObjectId ? value.id.toString() : value.id\n };\n }\n\n // Handle nested objects\n if (typeof value === \"object\") {\n return this.convertFromMongoValues(value);\n }\n\n return value;\n }\n\n /**\n * Convert values to MongoDB format for storage\n */\n private convertToMongoValues(values: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(values)) {\n result[key] = this.convertToMongoValue(value);\n }\n\n return result;\n }\n\n /**\n * Convert a single value to MongoDB format\n */\n private convertToMongoValue(value: any): any {\n if (value === null || value === undefined) return value;\n\n // Handle EntityReference\n if (typeof value === \"object\" && value.isEntityReference?.()) {\n return {\n id: ObjectId.isValid(value.id) ? new ObjectId(value.id) : value.id,\n path: value.path\n };\n }\n\n // Handle Date\n if (value instanceof Date) {\n return value;\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n return value.map(v => this.convertToMongoValue(v));\n }\n\n // Handle nested objects\n if (typeof value === \"object\") {\n return this.convertToMongoValues(value);\n }\n\n return value;\n }\n\n // =============================================================\n // EntityRepository Implementation\n // =============================================================\n\n /**\n * Fetch a single entity by ID\n */\n async fetchEntity<M extends Record<string, any>>(\n collectionPath: string,\n entityId: string | number,\n _databaseId?: string\n ): Promise<Entity<M> | undefined> {\n const collection = this.getCollection(collectionPath);\n const id = this.toObjectId(entityId);\n\n const doc = await collection.findOne({ _id: id } as Filter<Document>);\n\n if (!doc) return undefined;\n\n return this.documentToEntity<M>(doc, collectionPath);\n }\n\n /**\n * Fetch a collection of entities with optional filtering, ordering, and pagination\n */\n async fetchCollection<M extends Record<string, any>>(\n collectionPath: string,\n options: {\n filter?: FilterValues<Extract<keyof M, string>>;\n orderBy?: string;\n order?: \"desc\" | \"asc\";\n limit?: number;\n startAfter?: any;\n searchString?: string;\n databaseId?: string;\n collection?: EntityCollection;\n } = {}\n ): Promise<Entity<M>[]> {\n const collection = this.getCollection(collectionPath);\n\n // Build query\n const query = MongoConditionBuilder.buildQuery<M>({\n filter: options.filter,\n searchString: options.searchString,\n properties: options.collection?.properties ?? {}\n });\n\n // Build find options\n const findOptions: FindOptions<Document> = {};\n\n // Apply sorting\n const sort = MongoConditionBuilder.buildSort(options.orderBy, options.order);\n if (sort) {\n findOptions.sort = sort;\n }\n\n // Apply limit\n if (options.limit) {\n findOptions.limit = options.limit;\n }\n\n // Apply pagination (skip-based for now, cursor-based would be better)\n if (options.startAfter !== undefined) {\n findOptions.skip = Number(options.startAfter);\n }\n\n const docs = await collection.find(query, findOptions).toArray();\n\n return docs.map((doc: Document) => this.documentToEntity<M>(doc, collectionPath));\n }\n\n /**\n * Search entities by text\n */\n async searchEntities<M extends Record<string, any>>(\n collectionPath: string,\n searchString: string,\n options: {\n filter?: FilterValues<Extract<keyof M, string>>;\n orderBy?: string;\n order?: \"desc\" | \"asc\";\n limit?: number;\n databaseId?: string;\n collection?: EntityCollection;\n } = {}\n ): Promise<Entity<M>[]> {\n return this.fetchCollection<M>(collectionPath, {\n ...options,\n searchString\n });\n }\n\n /**\n * Count entities in a collection\n */\n async countEntities<M extends Record<string, any>>(\n collectionPath: string,\n options: {\n filter?: FilterValues<Extract<keyof M, string>>;\n databaseId?: string;\n } = {}\n ): Promise<number> {\n const collection = this.getCollection(collectionPath);\n\n const query = options.filter\n ? MongoConditionBuilder.buildQuery<M>({ filter: options.filter })\n : {};\n\n return collection.countDocuments(query);\n }\n\n /**\n * Save an entity (create or update)\n */\n async saveEntity<M extends Record<string, any>>(\n collectionPath: string,\n values: Partial<M>,\n entityId?: string | number,\n _databaseId?: string\n ): Promise<Entity<M>> {\n const collection = this.getCollection(collectionPath);\n const mongoValues = this.convertToMongoValues(values as Record<string, any>);\n\n if (entityId) {\n // Update existing entity\n const id = this.toObjectId(entityId);\n await collection.updateOne(\n { _id: id } as Filter<Document>,\n { $set: mongoValues },\n { upsert: true }\n );\n\n return {\n id: entityId.toString(),\n path: collectionPath,\n values: values as M\n };\n } else {\n // Create new entity\n const newId = new ObjectId();\n await collection.insertOne({\n _id: newId,\n ...mongoValues\n });\n\n return {\n id: newId.toString(),\n path: collectionPath,\n values: values as M\n };\n }\n }\n\n /**\n * Delete an entity by ID\n */\n async deleteEntity(\n collectionPath: string,\n entityId: string | number,\n _databaseId?: string\n ): Promise<void> {\n const collection = this.getCollection(collectionPath);\n const id = this.toObjectId(entityId);\n\n const result = await collection.deleteOne({ _id: id } as Filter<Document>);\n\n if (result.deletedCount === 0) {\n console.warn(`Entity ${entityId} not found in collection ${collectionPath}`);\n }\n }\n\n /**\n * Check if a field value is unique in a collection\n */\n async checkUniqueField(\n collectionPath: string,\n fieldName: string,\n value: any,\n excludeEntityId?: string,\n _databaseId?: string\n ): Promise<boolean> {\n const collection = this.getCollection(collectionPath);\n\n const query: Filter<Document> = { [fieldName]: value };\n\n if (excludeEntityId) {\n const id = this.toObjectId(excludeEntityId);\n (query as Record<string, unknown>)._id = { $ne: id };\n }\n\n const count = await collection.countDocuments(query);\n return count === 0;\n }\n\n /**\n * Generate a new entity ID\n */\n generateEntityId(): string {\n return new ObjectId().toString();\n }\n}\n","/**\n * MongoDB Realtime Service\n *\n * Implements RealtimeProvider interface using MongoDB Change Streams.\n * Provides real-time subscriptions to collection and entity changes.\n */\n\nimport { Db, ChangeStream, ChangeStreamDocument, Document, ObjectId } from \"mongodb\";\nimport {\n Entity,\n FilterValues,\n RealtimeProvider,\n CollectionSubscriptionConfig,\n EntitySubscriptionConfig,\n WebSocketMessage\n} from \"@rebasepro/types\";\nimport { WebSocket } from \"ws\";\nimport { MongoEntityService } from \"../db/MongoEntityService\";\n\ninterface Subscription {\n type: \"collection\" | \"entity\";\n config: CollectionSubscriptionConfig | EntitySubscriptionConfig;\n changeStream?: ChangeStream;\n callback?: (data: any) => void;\n}\n\n/**\n * MongoDB Realtime Service\n *\n * Implements real-time subscriptions using MongoDB Change Streams.\n * Requires MongoDB replica set for change streams to work.\n */\nexport class MongoRealtimeService implements RealtimeProvider {\n private subscriptions = new Map<string, Subscription>();\n private clients = new Map<string, WebSocket>();\n private entityService: MongoEntityService;\n\n constructor(private db: Db) {\n this.entityService = new MongoEntityService(db);\n }\n\n /**\n * Get the collection name from a path\n */\n private getCollectionName(path: string): string {\n return path.replace(/\\//g, \"_\");\n }\n\n /**\n * Subscribe to collection changes\n */\n subscribeToCollection(\n subscriptionId: string,\n config: CollectionSubscriptionConfig,\n callback?: (entities: Entity[]) => void\n ): void {\n // Clean up existing subscription if any\n this.unsubscribe(subscriptionId);\n\n const collectionName = this.getCollectionName(config.path);\n const collection = this.db.collection(collectionName);\n\n // Build pipeline for change stream filtering\n const pipeline: Document[] = [];\n\n // Filter by operation types we care about\n pipeline.push({\n $match: {\n operationType: { $in: [\"insert\", \"update\", \"replace\", \"delete\"] }\n }\n });\n\n try {\n // Create change stream\n const changeStream = collection.watch(pipeline, {\n fullDocument: \"updateLookup\"\n });\n\n const subscription: Subscription = {\n type: \"collection\",\n config,\n changeStream,\n callback\n };\n\n this.subscriptions.set(subscriptionId, subscription);\n\n // Fetch initial data\n this.fetchAndNotifyCollection(subscriptionId, config, callback);\n\n // Listen for changes\n changeStream.on(\"change\", async (change: ChangeStreamDocument) => {\n // Re-fetch the entire collection when any change happens\n // This is simpler and ensures consistent sorting/filtering\n await this.fetchAndNotifyCollection(subscriptionId, config, callback);\n });\n\n changeStream.on(\"error\", (error: Error) => {\n console.error(`Change stream error for subscription ${subscriptionId}:`, error);\n });\n\n } catch (error) {\n // Change streams might not be available (e.g., standalone MongoDB)\n console.warn(\"Change streams not available, falling back to polling:\", error);\n\n // Store subscription without change stream for manual notifications\n const subscription: Subscription = {\n type: \"collection\",\n config,\n callback\n };\n\n this.subscriptions.set(subscriptionId, subscription);\n\n // Fetch initial data\n this.fetchAndNotifyCollection(subscriptionId, config, callback);\n }\n }\n\n /**\n * Fetch collection and notify callback\n */\n private async fetchAndNotifyCollection(\n subscriptionId: string,\n config: CollectionSubscriptionConfig,\n callback?: (entities: Entity[]) => void\n ): Promise<void> {\n try {\n const entities = await this.entityService.fetchCollection(config.path, {\n filter: config.filter as FilterValues<string> | undefined,\n orderBy: config.orderBy,\n order: config.order,\n limit: config.limit,\n startAfter: config.startAfter,\n searchString: config.searchString\n });\n\n if (callback) {\n callback(entities);\n }\n } catch (error) {\n console.error(`Error fetching collection for subscription ${subscriptionId}:`, error);\n }\n }\n\n /**\n * Subscribe to single entity changes\n */\n subscribeToEntity(\n subscriptionId: string,\n config: EntitySubscriptionConfig,\n callback?: (entity: Entity | null) => void\n ): void {\n // Clean up existing subscription if any\n this.unsubscribe(subscriptionId);\n\n const collectionName = this.getCollectionName(config.path);\n const collection = this.db.collection(collectionName);\n\n // Build pipeline to watch specific document\n const entityId = typeof config.entityId === \"string\" && ObjectId.isValid(config.entityId)\n ? new ObjectId(config.entityId)\n : config.entityId;\n\n const pipeline: Document[] = [\n {\n $match: {\n \"documentKey._id\": entityId,\n operationType: { $in: [\"insert\", \"update\", \"replace\", \"delete\"] }\n }\n }\n ];\n\n try {\n const changeStream = collection.watch(pipeline, {\n fullDocument: \"updateLookup\"\n });\n\n const subscription: Subscription = {\n type: \"entity\",\n config,\n changeStream,\n callback\n };\n\n this.subscriptions.set(subscriptionId, subscription);\n\n // Fetch initial data\n this.fetchAndNotifyEntity(subscriptionId, config, callback);\n\n // Listen for changes\n changeStream.on(\"change\", async (change: ChangeStreamDocument) => {\n if (change.operationType === \"delete\") {\n if (callback) {\n callback(null);\n }\n } else {\n await this.fetchAndNotifyEntity(subscriptionId, config, callback);\n }\n });\n\n changeStream.on(\"error\", (error: Error) => {\n console.error(`Change stream error for subscription ${subscriptionId}:`, error);\n });\n\n } catch (error) {\n console.warn(\"Change streams not available, falling back to polling:\", error);\n\n const subscription: Subscription = {\n type: \"entity\",\n config,\n callback\n };\n\n this.subscriptions.set(subscriptionId, subscription);\n\n // Fetch initial data\n this.fetchAndNotifyEntity(subscriptionId, config, callback);\n }\n }\n\n /**\n * Fetch entity and notify callback\n */\n private async fetchAndNotifyEntity(\n subscriptionId: string,\n config: EntitySubscriptionConfig,\n callback?: (entity: Entity | null) => void\n ): Promise<void> {\n try {\n const entity = await this.entityService.fetchEntity(config.path, config.entityId);\n\n if (callback) {\n callback(entity || null);\n }\n } catch (error) {\n console.error(`Error fetching entity for subscription ${subscriptionId}:`, error);\n }\n }\n\n /**\n * Unsubscribe from a subscription\n */\n unsubscribe(subscriptionId: string): void {\n const subscription = this.subscriptions.get(subscriptionId);\n if (subscription) {\n if (subscription.changeStream) {\n subscription.changeStream.close().catch(console.error);\n }\n this.subscriptions.delete(subscriptionId);\n }\n }\n\n /**\n * Notify all relevant subscribers of an entity update\n * This is called after save/delete operations to push updates\n */\n async notifyEntityUpdate(\n path: string,\n entityId: string,\n entity: Entity | null,\n _databaseId?: string\n ): Promise<void> {\n // Find all subscriptions that might be affected by this update\n for (const [subscriptionId, subscription] of this.subscriptions) {\n if (subscription.type === \"entity\") {\n const config = subscription.config as EntitySubscriptionConfig;\n if (config.path === path && config.entityId.toString() === entityId) {\n if (subscription.callback) {\n subscription.callback(entity);\n }\n }\n } else if (subscription.type === \"collection\") {\n const config = subscription.config as CollectionSubscriptionConfig;\n if (config.path === path) {\n // Re-fetch the collection to get updated data\n await this.fetchAndNotifyCollection(subscriptionId, config, subscription.callback);\n }\n }\n }\n }\n\n /**\n * Get all active subscriptions (for debugging)\n */\n getSubscriptions(): Map<string, Subscription> {\n return this.subscriptions;\n }\n\n /**\n * Close all subscriptions\n */\n async closeAll(): Promise<void> {\n for (const [subscriptionId] of this.subscriptions) {\n this.unsubscribe(subscriptionId);\n }\n }\n\n // =============================================================================\n // WebSocket Client Management (parity with PostgreSQL RealtimeService)\n // =============================================================================\n\n /**\n * Register a WebSocket client for real-time communication\n */\n addClient(clientId: string, ws: WebSocket) {\n this.clients.set(clientId, ws);\n\n ws.on(\"close\", () => {\n this.removeClient(clientId);\n });\n\n ws.on(\"error\", (error) => {\n console.error(\"WebSocket error for client\", clientId, error);\n this.removeClient(clientId);\n });\n }\n\n /**\n * Remove a WebSocket client and clean up its subscriptions\n */\n private removeClient(clientId: string) {\n this.clients.delete(clientId);\n }\n\n /**\n * Handle an incoming WebSocket message for subscription management\n */\n async handleClientMessage(\n clientId: string,\n message: { type: string; payload?: any; subscriptionId?: string },\n _authContext?: { userId: string; roles: unknown[] }\n ): Promise<void> {\n const ws = this.clients.get(clientId);\n if (!ws) return;\n\n switch (message.type) {\n case \"subscribe_collection\": {\n const subscriptionId = message.payload?.subscriptionId ?? message.subscriptionId;\n if (!subscriptionId) return;\n\n this.subscribeToCollection(\n subscriptionId,\n {\n clientId,\n path: message.payload?.path,\n filter: message.payload?.filter,\n orderBy: message.payload?.orderBy,\n order: message.payload?.order,\n limit: message.payload?.limit,\n startAfter: message.payload?.startAfter,\n searchString: message.payload?.searchString\n },\n (entities) => {\n ws.send(JSON.stringify({\n type: \"collection_update\",\n subscriptionId,\n entities\n }));\n }\n );\n break;\n }\n case \"subscribe_entity\": {\n const subscriptionId = message.payload?.subscriptionId ?? message.subscriptionId;\n if (!subscriptionId) return;\n\n this.subscribeToEntity(\n subscriptionId,\n {\n clientId,\n path: message.payload?.path,\n entityId: message.payload?.entityId\n },\n (entity) => {\n ws.send(JSON.stringify({\n type: \"entity_update\",\n subscriptionId,\n entity\n }));\n }\n );\n break;\n }\n case \"unsubscribe\": {\n const subscriptionId = message.payload?.subscriptionId ?? message.subscriptionId;\n if (subscriptionId) {\n this.unsubscribe(subscriptionId);\n }\n break;\n }\n }\n }\n}\n","import { Db, ObjectId } from \"mongodb\";\n\n/**\n * Shallow comparison to find top-level keys that changed between two objects.\n */\nexport function findChangedFields(\n oldValues: Record<string, unknown>,\n newValues: Record<string, unknown>\n): string[] | null {\n const changed: string[] = [];\n const allKeys = new Set([\n ...Object.keys(oldValues),\n ...Object.keys(newValues)\n ]);\n\n for (const key of allKeys) {\n const oldVal = oldValues[key];\n const newVal = newValues[key];\n\n // Skip internal metadata\n if (key.startsWith(\"__\")) continue;\n\n if (oldVal !== newVal) {\n // For objects/arrays, use JSON comparison\n if (\n typeof oldVal === \"object\" && oldVal !== null &&\n typeof newVal === \"object\" && newVal !== null\n ) {\n if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n changed.push(key);\n }\n } else {\n changed.push(key);\n }\n }\n }\n\n return changed.length > 0 ? changed : null;\n}\n\nexport interface HistoryEntry {\n _id?: ObjectId;\n id: string;\n table_name: string;\n entity_id: string;\n action: \"create\" | \"update\" | \"delete\";\n changed_fields: string[] | null;\n values: Record<string, unknown> | null;\n previous_values: Record<string, unknown> | null;\n updated_by: string | null;\n updated_at: Date;\n}\n\nexport interface RecordHistoryParams {\n tableName: string;\n entityId: string;\n action: \"create\" | \"update\" | \"delete\";\n values?: Record<string, unknown> | null;\n previousValues?: Record<string, unknown> | null;\n updatedBy?: string | null;\n}\n\nexport interface HistoryRetentionConfig {\n maxEntries: number;\n ttlDays: number;\n}\n\nconst DEFAULT_RETENTION: HistoryRetentionConfig = {\n maxEntries: 200,\n ttlDays: 90\n};\n\nexport class MongoHistoryService {\n public retention: HistoryRetentionConfig;\n\n constructor(\n private db: Db,\n retention?: Partial<HistoryRetentionConfig>\n ) {\n this.retention = { ...DEFAULT_RETENTION, ...retention };\n }\n\n async recordHistory(params: RecordHistoryParams): Promise<void> {\n const {\n tableName,\n entityId,\n action,\n values,\n previousValues,\n updatedBy\n } = params;\n\n const changedFields = previousValues && values\n ? findChangedFields(previousValues, values)\n : null;\n\n if (action === \"update\" && (!changedFields || changedFields.length === 0)) {\n return;\n }\n\n try {\n const entry: HistoryEntry = {\n id: new ObjectId().toString(),\n table_name: tableName,\n entity_id: String(entityId),\n action,\n changed_fields: changedFields,\n values: values || null,\n previous_values: previousValues || null,\n updated_by: updatedBy || null,\n updated_at: new Date()\n };\n\n await this.db.collection(\"__rebase_history\").insertOne(entry);\n\n // Non-blocking prune for this specific entity\n this.pruneHistory(String(entityId), tableName).catch(e => {\n console.error(`[HistoryService] Failed to prune history for ${tableName}/${entityId}:`, e);\n });\n } catch (error) {\n console.error(`[HistoryService] Failed to record history for ${tableName}/${entityId}:`, error);\n }\n }\n\n private async pruneHistory(entityId: string, tableName: string): Promise<void> {\n const collection = this.db.collection(\"__rebase_history\");\n\n // 1. Enforce maxEntries\n const count = await collection.countDocuments({ entity_id: entityId, table_name: tableName });\n if (count > this.retention.maxEntries) {\n const toDelete = count - this.retention.maxEntries;\n const oldestEntries = await collection\n .find({ entity_id: entityId, table_name: tableName })\n .sort({ updated_at: 1 })\n .limit(toDelete)\n .toArray();\n\n if (oldestEntries.length > 0) {\n const idsToDelete = oldestEntries.map(entry => entry._id);\n await collection.deleteMany({ _id: { $in: idsToDelete } });\n }\n }\n\n // 2. Enforce ttlDays\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.retention.ttlDays);\n\n await collection.deleteMany({\n entity_id: entityId,\n table_name: tableName,\n updated_at: { $lt: cutoffDate }\n });\n }\n}\n","/**\n * MongoDB DataDriver Delegate\n *\n * Implements the DataDriver interface for Rebase frontend integration.\n * This is the main entry point for Rebase to interact with MongoDB.\n */\n\nimport { Db, ObjectId } from \"mongodb\";\nimport {\n DataDriver,\n DeleteEntityProps,\n Entity,\n EntityCollection,\n FetchCollectionProps,\n FetchEntityProps,\n ListenCollectionProps,\n ListenEntityProps,\n SaveEntityProps\n} from \"@rebasepro/types\";\nimport { MongoEntityService } from \"../db/MongoEntityService\";\nimport { MongoRealtimeService } from \"./MongoRealtimeService\";\nimport { MongoHistoryService } from \"./MongoHistoryService\";\n\n/**\n * MongoDB DataDriver Delegate\n *\n * Implements the DataDriver interface for Rebase.\n * Provides all data operations needed by the Rebase frontend.\n */\nexport class MongoDriver implements DataDriver {\n key = \"mongodb\";\n initialised = true;\n\n private entityService: MongoEntityService;\n private realtimeService: MongoRealtimeService;\n public historyService: MongoHistoryService;\n\n constructor(\n private db: Db,\n realtimeService?: MongoRealtimeService,\n historyService?: MongoHistoryService\n ) {\n this.entityService = new MongoEntityService(db);\n this.realtimeService = realtimeService ?? new MongoRealtimeService(db);\n this.historyService = historyService ?? new MongoHistoryService(db);\n }\n\n\n /**\n * Get the current timestamp\n */\n currentTime(): Date {\n return new Date();\n }\n\n /**\n * Fetch a collection of entities\n */\n async fetchCollection<M extends Record<string, any>>({\n path,\n collection,\n filter,\n limit,\n startAfter,\n orderBy,\n searchString,\n order\n }: FetchCollectionProps<M>): Promise<Entity<M>[]> {\n return this.entityService.fetchCollection<M>(path, {\n filter,\n limit,\n startAfter,\n orderBy,\n order,\n searchString,\n collection: collection as unknown as EntityCollection\n });\n }\n\n /**\n * Listen to collection changes\n */\n listenCollection<M extends Record<string, any>>({\n path,\n collection,\n filter,\n limit,\n startAfter,\n orderBy,\n searchString,\n order,\n onUpdate,\n onError\n }: ListenCollectionProps<M>): () => void {\n const subscriptionId = this.generateSubscriptionId();\n\n const callback = (entities: Entity<any>[]) => {\n try {\n onUpdate(entities as Entity<M>[]);\n } catch (error) {\n console.error(\"Error in collection update callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n };\n\n this.realtimeService.subscribeToCollection(\n subscriptionId,\n {\n clientId: \"driver\",\n path,\n filter,\n orderBy,\n order,\n limit,\n startAfter,\n searchString\n },\n callback\n );\n\n // Return unsubscribe function\n return () => {\n this.realtimeService.unsubscribe(subscriptionId);\n };\n }\n\n /**\n * Fetch a single entity\n */\n async fetchEntity<M extends Record<string, any>>({\n path,\n entityId,\n databaseId,\n collection\n }: FetchEntityProps<M>): Promise<Entity<M> | undefined> {\n return this.entityService.fetchEntity<M>(path, entityId, databaseId);\n }\n\n /**\n * Listen to entity changes\n */\n listenEntity<M extends Record<string, any>>({\n path,\n entityId,\n collection,\n onUpdate,\n onError\n }: ListenEntityProps<M>): () => void {\n const subscriptionId = this.generateSubscriptionId();\n\n const callback = (entity: Entity<any> | null) => {\n try {\n onUpdate(entity as Entity<M>);\n } catch (error) {\n console.error(\"Error in entity update callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n };\n\n this.realtimeService.subscribeToEntity(\n subscriptionId,\n {\n clientId: \"driver\",\n path,\n entityId\n },\n callback\n );\n\n // Return unsubscribe function\n return () => {\n this.realtimeService.unsubscribe(subscriptionId);\n };\n }\n\n /**\n * Save an entity (create or update)\n */\n async saveEntity<M extends Record<string, any>>({\n path,\n entityId,\n values,\n previousValues,\n collection,\n status\n }: SaveEntityProps<M>): Promise<Entity<M>> {\n const isNew = status === \"new\" || !previousValues;\n\n const entity = await this.entityService.saveEntity<M>(path, values, entityId);\n\n // Handle history recording\n if (collection?.history) {\n this.historyService.recordHistory({\n action: isNew ? \"create\" : \"update\",\n entityId: String(entity.id),\n tableName: path,\n values: entity.values,\n previousValues: isNew ? undefined : previousValues,\n }).catch(err => {\n // Fire and forget, don't fail the save operation\n console.error(`Failed to record history for ${path}/${entity.id}:`, err);\n });\n }\n\n // Notify subscribers of the update\n await this.realtimeService.notifyEntityUpdate(path, String(entity.id), entity);\n\n return entity;\n }\n\n /**\n * Delete an entity\n */\n async deleteEntity<M extends Record<string, any>>({\n entity,\n collection\n }: DeleteEntityProps<M>): Promise<void> {\n await this.entityService.deleteEntity(entity.path, entity.id);\n\n if (collection?.history) {\n this.historyService.recordHistory({\n action: \"delete\",\n entityId: String(entity.id),\n tableName: entity.path,\n previousValues: entity.values,\n }).catch(err => {\n console.error(`Failed to record history for ${entity.path}/${entity.id}:`, err);\n });\n }\n\n // Notify subscribers of the deletion\n await this.realtimeService.notifyEntityUpdate(entity.path, String(entity.id), null);\n }\n\n /**\n * Check if a field value is unique\n */\n async checkUniqueField(\n path: string,\n name: string,\n value: any,\n entityId?: string,\n collection?: EntityCollection\n ): Promise<boolean> {\n return this.entityService.checkUniqueField(path, name, value, entityId);\n }\n\n /**\n * Generate a new entity ID\n */\n generateEntityId(path: string, collection?: EntityCollection): string {\n return this.entityService.generateEntityId();\n }\n\n /**\n * Count entities in a collection\n */\n async countEntities<M extends Record<string, any>>({\n path,\n collection,\n filter\n }: FetchCollectionProps<M>): Promise<number> {\n return this.entityService.countEntities<M>(path, { filter });\n }\n\n /**\n * Generate a unique subscription ID\n */\n private generateSubscriptionId(): string {\n return `mongo_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n }\n\n /**\n * Check if the delegate is ready\n */\n isReady(): boolean {\n return this.initialised;\n }\n\n /**\n * Get the underlying entity service for direct access\n */\n getEntityService(): MongoEntityService {\n return this.entityService;\n }\n\n /**\n * Get the underlying realtime service for direct access\n */\n getRealtimeService(): MongoRealtimeService {\n return this.realtimeService;\n }\n}\n","/**\n * MongoDB Backend Factory\n *\n * This module provides factory functions for creating MongoDB backend instances.\n * It abstracts the creation of drivers, realtime services, and entity services.\n */\n\nimport { Db, MongoClient } from \"mongodb\";\nimport { DataDriver, EntityCollection } from \"@rebasepro/types\";\n\nimport { MongoEntityService } from \"./db/MongoEntityService\";\nimport { MongoRealtimeService } from \"./services/MongoRealtimeService\";\nimport { MongoDriver } from \"./services/MongoDriver\";\nimport { MongoHistoryService, HistoryRetentionConfig } from \"./services/MongoHistoryService\";\nimport { MongoDBConnection } from \"./connection\";\nimport { BackendConfig, BackendInstance, CollectionRegistryInterface, EntityRepository, RealtimeProvider, DatabaseConnection, DatabaseAdmin, DocumentAdmin, SchemaAdmin, HealthCheckResult } from \"@rebasepro/types\";\n\n/**\n * Configuration for creating a MongoDB backend.\n */\nexport interface MongoBackendConfig extends BackendConfig {\n type: \"mongodb\";\n /** MongoDB database instance */\n connection: Db;\n /** MongoDB client (for connection management) */\n client: MongoClient;\n /** Collections to register (optional, can be registered later) */\n collections?: EntityCollection[];\n /** History retention configuration */\n historyRetention?: Partial<HistoryRetentionConfig>;\n}\n\n/**\n * MongoDB-specific backend instance with additional MongoDB types.\n */\nexport interface MongoBackendInstance extends BackendInstance {\n /** The MongoDB database instance */\n db: Db;\n /** The MongoDB client */\n client: MongoClient;\n /** MongoDB DataDriver for use with Rebase */\n driver: DataDriver;\n /** Entity service for direct database operations */\n entityService: MongoEntityService;\n /** Realtime service for subscriptions */\n realtimeService: MongoRealtimeService;\n /** Admin capabilities (DocumentAdmin + SchemaAdmin) */\n admin: DatabaseAdmin;\n}\n\n// =============================================================================\n// Simple Collection Registry\n// =============================================================================\n\n/**\n * Simple in-memory collection registry for MongoDB.\n */\nexport class MongoCollectionRegistry implements CollectionRegistryInterface {\n private collections = new Map<string, EntityCollection>();\n\n /**\n * Register a collection\n */\n register(collection: EntityCollection): void {\n this.collections.set(collection.name, collection);\n }\n\n /**\n * Get a collection by its path\n */\n getCollectionByPath(path: string): EntityCollection | undefined {\n return this.collections.get(path);\n }\n\n /**\n * Get all registered collections\n */\n getCollections(): EntityCollection[] {\n return Array.from(this.collections.values());\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a complete MongoDB backend instance.\n *\n * This factory function creates all the necessary services for a MongoDB backend:\n * - MongoDBConnection (database connection wrapper)\n * - MongoEntityService (implements EntityRepository)\n * - MongoRealtimeService (implements RealtimeProvider)\n * - MongoCollectionRegistry (implements CollectionRegistryInterface)\n * - MongoDriver (for Rebase integration)\n *\n * @example\n * ```typescript\n * import { createMongoBackend } from \"@rebasepro/server-mongodb\";\n *\n * const client = new MongoClient(\"mongodb://localhost:27017\");\n * await client.connect();\n * const db = client.db(\"my_database\");\n *\n * const backend = createMongoBackend({\n * type: \"mongodb\",\n * connection: db,\n * client: client,\n * collections: myCollections\n * });\n *\n * // Use the backend\n * const entities = await backend.entityRepository.fetchCollection(\"users\", {});\n * ```\n */\nexport function createMongoBackend(config: MongoBackendConfig): MongoBackendInstance {\n const { connection: db, client, collections } = config;\n\n // Create collection registry\n const collectionRegistry = new MongoCollectionRegistry();\n\n // Register collections if provided\n if (collections) {\n collections.forEach(collection => collectionRegistry.register(collection));\n }\n\n // Create services\n const entityService = new MongoEntityService(db);\n const realtimeService = new MongoRealtimeService(db);\n const historyService = new MongoHistoryService(db, config.historyRetention);\n const driver = new MongoDriver(db, realtimeService, historyService);\n const mongoConnection = new MongoDBConnection(db, client);\n\n // Build admin capabilities for MongoDB\n const admin: DatabaseAdmin = {\n async executeAggregate(pipeline: Record<string, unknown>[]) {\n // Run aggregation on a collection — requires a target collection\n // from the pipeline's $match or $lookup stage:\n const firstStage = pipeline[0];\n const collName = typeof firstStage.$from === \"string\" ? firstStage.$from : \"__admin__\";\n const cursor = db.collection(collName).aggregate(pipeline);\n return await cursor.toArray() as Record<string, unknown>[];\n },\n async fetchCollectionStats(collectionName: string) {\n const stats = await db.command({ collStats: collectionName }) as { count: number; size: number };\n return { count: stats.count,\nsizeBytes: stats.size };\n },\n async fetchUnmappedTables(mappedPaths?: string[]) {\n const allCollections = await db.listCollections().toArray();\n const names = allCollections.map(c => c.name).filter(n => !n.startsWith(\"system.\"));\n if (!mappedPaths || mappedPaths.length === 0) return names;\n const mappedSet = new Set(mappedPaths.map(p => p.toLowerCase()));\n return names.filter(n => !mappedSet.has(n.toLowerCase()));\n },\n async fetchTableMetadata(collectionName: string) {\n // Sample a document to infer fields\n const sample = await db.collection(collectionName).findOne();\n if (!sample) return { columns: [],\nforeignKeys: [],\njunctions: [],\npolicies: [] };\n const columns = Object.entries(sample).map(([key, value]) => ({\n column_name: key,\n data_type: typeof value,\n udt_name: typeof value,\n is_nullable: \"YES\",\n column_default: null,\n character_maximum_length: null\n }));\n return { columns,\nforeignKeys: [],\njunctions: [],\npolicies: [] };\n }\n } satisfies DocumentAdmin & SchemaAdmin;\n\n return {\n // Abstract interface implementations\n connection: mongoConnection,\n entityRepository: entityService,\n realtimeProvider: realtimeService,\n collectionRegistry: collectionRegistry,\n admin,\n\n // Lifecycle\n async initialize() {\n // Connection is already established via the MongoClient constructor\n },\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n try {\n await db.command({ ping: 1 });\n return { healthy: true,\nlatencyMs: Date.now() - start };\n } catch {\n return { healthy: false,\nlatencyMs: Date.now() - start };\n }\n },\n async destroy() {\n await client.close();\n },\n\n // MongoDB-specific accessors\n db,\n client,\n driver,\n entityService,\n realtimeService\n };\n}\n\n/**\n * Create a MongoDB DataDriver.\n *\n * This is a convenience function when you only need the DataDriver\n * without the full backend instance.\n *\n * @example\n * ```typescript\n * import { createMongoDelegate } from \"@rebasepro/server-mongodb\";\n *\n * const delegate = createMongoDelegate(db);\n * ```\n */\nexport function createMongoDelegate(\n db: Db,\n realtimeService?: MongoRealtimeService,\n historyService?: MongoHistoryService\n): MongoDriver {\n const realtime = realtimeService ?? new MongoRealtimeService(db);\n const history = historyService ?? new MongoHistoryService(db);\n return new MongoDriver(db, realtime, history);\n}\n\n/**\n * Create a RealtimeService for MongoDB.\n *\n * @example\n * ```typescript\n * import { createMongoRealtimeService } from \"@rebasepro/server-mongodb\";\n *\n * const realtimeService = createMongoRealtimeService(db);\n * ```\n */\nexport function createMongoRealtimeService(db: Db): MongoRealtimeService {\n return new MongoRealtimeService(db);\n}\n\n/**\n * Create a MongoDB entity repository.\n *\n * @example\n * ```typescript\n * import { createMongoEntityRepository } from \"@rebasepro/server-mongodb\";\n *\n * const repository = createMongoEntityRepository(db);\n * const users = await repository.fetchCollection(\"users\", {});\n * ```\n */\nexport function createMongoEntityRepository(db: Db): EntityRepository {\n return new MongoEntityService(db);\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Check if a backend config is for MongoDB.\n */\nexport function isMongoBackendConfig(config: BackendConfig): config is MongoBackendConfig {\n return config.type === \"mongodb\" &&\n typeof (config as MongoBackendConfig).connection !== \"undefined\" &&\n typeof (config as MongoBackendConfig).client !== \"undefined\";\n}\n\n/**\n * Check if a driver config is for MongoDB.\n */\nexport function isMongoDriverConfig(obj: unknown): obj is { type: \"mongodb\"; connection: Db; client: MongoClient } {\n return typeof obj === \"object\" &&\n obj !== null &&\n \"type\" in obj &&\n (obj as Record<string, unknown>).type === \"mongodb\" &&\n \"connection\" in obj &&\n \"client\" in obj;\n}\n","import { Db, ObjectId } from \"mongodb\";\n\n/** Loose document type that allows string _id values (Rebase convention). */\nexport interface MongoDoc { _id?: string; [key: string]: any; }\nimport {\n UserRepository,\n RoleRepository,\n TokenRepository,\n AuthRepository,\n UserData,\n CreateUserData,\n RoleData,\n CreateRoleData,\n RefreshTokenInfo,\n PasswordResetTokenInfo,\n UserIdentityData,\n ListUsersOptions,\n PaginatedUsersResult\n// @ts-ignore\n} from \"@rebasepro/server-core\";\n\nexport type Role = RoleData;\n\nfunction toUser(doc: any): UserData {\n return {\n id: doc._id || doc.id,\n email: doc.email,\n passwordHash: doc.passwordHash ?? null,\n displayName: doc.displayName ?? null,\n photoUrl: doc.photoUrl ?? null,\n emailVerified: doc.emailVerified ?? false,\n emailVerificationToken: doc.emailVerificationToken ?? null,\n emailVerificationSentAt: doc.emailVerificationSentAt ? new Date(doc.emailVerificationSentAt) : null,\n createdAt: new Date(doc.createdAt),\n updatedAt: new Date(doc.updatedAt)\n };\n}\n\nexport class MongoUserService implements UserRepository {\n constructor(private db: Db) {}\n\n private get collection() {\n return this.db.collection<MongoDoc>(\"rebase_users\");\n }\n \n private get identitiesCollection() {\n return this.db.collection<MongoDoc>(\"rebase_user_identities\");\n }\n\n private get userRolesCollection() {\n return this.db.collection<MongoDoc>(\"rebase_user_roles\");\n }\n\n private get rolesCollection() {\n return this.db.collection<MongoDoc>(\"rebase_roles\");\n }\n\n async createUser(data: CreateUserData): Promise<UserData> {\n const id = new ObjectId().toString();\n const now = new Date();\n const doc = {\n _id: id,\n id,\n email: data.email.toLowerCase(),\n passwordHash: data.passwordHash ?? null,\n displayName: data.displayName ?? null,\n photoUrl: data.photoUrl ?? null,\n emailVerified: data.emailVerified ?? false,\n createdAt: now,\n updatedAt: now\n };\n await this.collection.insertOne(doc);\n return toUser(doc);\n }\n\n async getUserById(id: string): Promise<UserData | null> {\n const doc = await this.collection.findOne({ id });\n return doc ? toUser(doc) : null;\n }\n\n async getUserByEmail(email: string): Promise<UserData | null> {\n const doc = await this.collection.findOne({ email: email.toLowerCase() });\n return doc ? toUser(doc) : null;\n }\n\n async getUserByIdentity(provider: string, providerId: string): Promise<UserData | null> {\n const identity = await this.identitiesCollection.findOne({ provider, providerId });\n if (!identity) return null;\n return this.getUserById(identity.userId);\n }\n\n async getUserIdentities(userId: string): Promise<UserIdentityData[]> {\n const docs = await this.identitiesCollection.find({ userId }).toArray();\n return docs.map(doc => ({\n id: doc.id,\n userId: doc.userId,\n provider: doc.provider,\n providerId: doc.providerId,\n profileData: doc.profileData ?? null,\n createdAt: new Date(doc.createdAt),\n updatedAt: new Date(doc.updatedAt)\n }));\n }\n\n async linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void> {\n const now = new Date();\n await this.identitiesCollection.updateOne(\n { provider, providerId },\n {\n $setOnInsert: {\n _id: new ObjectId().toString(),\n id: new ObjectId().toString(),\n userId,\n provider,\n providerId,\n createdAt: now\n },\n $set: {\n profileData: profileData ?? null,\n updatedAt: now\n }\n },\n { upsert: true }\n );\n }\n\n async updateUser(id: string, data: Partial<Omit<CreateUserData, \"id\">>): Promise<UserData | null> {\n const updateData: Record<string, unknown> = { ...data, updatedAt: new Date() };\n if (typeof updateData.email === \"string\") updateData.email = updateData.email.toLowerCase();\n \n await this.collection.updateOne({ id }, { $set: updateData });\n return this.getUserById(id);\n }\n\n async deleteUser(id: string): Promise<void> {\n await this.collection.deleteOne({ id });\n await this.identitiesCollection.deleteMany({ userId: id });\n await this.userRolesCollection.deleteMany({ userId: id });\n }\n\n async listUsers(): Promise<UserData[]> {\n const docs = await this.collection.find().toArray();\n return docs.map(toUser);\n }\n\n async listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult> {\n const limit = options?.limit ?? 25;\n const offset = options?.offset ?? 0;\n const search = options?.search?.trim() || \"\";\n const orderBy = options?.orderBy || \"createdAt\";\n const orderDir = options?.orderDir || \"desc\";\n const roleId = options?.roleId;\n\n const query: Record<string, unknown> = {};\n \n if (search) {\n query.$or = [\n { email: { $regex: search, $options: \"i\" } },\n { displayName: { $regex: search, $options: \"i\" } }\n ];\n }\n\n if (roleId) {\n const userRoles = await this.userRolesCollection.find({ roleId }).toArray();\n const userIds = userRoles.map(ur => ur.userId);\n query.id = { $in: userIds };\n }\n\n const sort: Record<string, 1 | -1> = {};\n sort[orderBy] = orderDir === \"asc\" ? 1 : -1;\n\n const total = await this.collection.countDocuments(query);\n const docs = await this.collection.find(query).sort(sort).skip(offset).limit(limit).toArray();\n\n return {\n users: docs.map(toUser),\n total,\n limit,\n offset\n };\n }\n\n async updatePassword(id: string, passwordHash: string): Promise<void> {\n await this.collection.updateOne(\n { id },\n { $set: { passwordHash, updatedAt: new Date() } }\n );\n }\n\n async setEmailVerified(id: string, verified: boolean): Promise<void> {\n await this.collection.updateOne(\n { id },\n { $set: { emailVerified: verified, emailVerificationToken: null, updatedAt: new Date() } }\n );\n }\n\n async setVerificationToken(id: string, token: string | null): Promise<void> {\n await this.collection.updateOne(\n { id },\n { $set: { emailVerificationToken: token, emailVerificationSentAt: token ? new Date() : null, updatedAt: new Date() } }\n );\n }\n\n async getUserByVerificationToken(token: string): Promise<UserData | null> {\n const doc = await this.collection.findOne({ emailVerificationToken: token });\n return doc ? toUser(doc) : null;\n }\n\n async getUserRoles(userId: string): Promise<RoleData[]> {\n const userRoles = await this.userRolesCollection.find({ userId }).toArray();\n const roleIds = userRoles.map(ur => ur.roleId);\n if (roleIds.length === 0) return [];\n\n const roles = await this.rolesCollection.find({ id: { $in: roleIds } }).toArray();\n return roles.map(r => ({\n id: r.id,\n name: r.name,\n isAdmin: r.isAdmin ?? false,\n defaultPermissions: r.defaultPermissions ?? null,\n collectionPermissions: r.collectionPermissions ?? null,\n config: r.config ?? null\n }));\n }\n\n async getUserRoleIds(userId: string): Promise<string[]> {\n const userRoles = await this.userRolesCollection.find({ userId }).toArray();\n return userRoles.map(ur => ur.roleId);\n }\n\n async setUserRoles(userId: string, roleIds: string[]): Promise<void> {\n await this.userRolesCollection.deleteMany({ userId });\n if (roleIds.length > 0) {\n const docs = roleIds.map(roleId => ({\n _id: new ObjectId().toString(),\n userId,\n roleId\n }));\n await this.userRolesCollection.insertMany(docs);\n }\n }\n\n async assignDefaultRole(userId: string, roleId: string): Promise<void> {\n await this.userRolesCollection.updateOne(\n { userId, roleId },\n { $setOnInsert: { _id: new ObjectId().toString(), userId, roleId } },\n { upsert: true }\n );\n }\n\n async getUserWithRoles(userId: string): Promise<{ user: UserData; roles: RoleData[] } | null> {\n const user = await this.getUserById(userId);\n if (!user) return null;\n const roles = await this.getUserRoles(userId);\n return { user, roles };\n }\n}\n\nexport class MongoRoleService implements RoleRepository {\n constructor(private db: Db) {}\n\n private get collection() {\n return this.db.collection<MongoDoc>(\"rebase_roles\");\n }\n\n async getRoleById(id: string): Promise<RoleData | null> {\n const doc = await this.collection.findOne({ id });\n if (!doc) return null;\n return {\n id: doc.id,\n name: doc.name,\n isAdmin: doc.isAdmin ?? false,\n defaultPermissions: doc.defaultPermissions ?? null,\n collectionPermissions: doc.collectionPermissions ?? null,\n config: doc.config ?? null\n };\n }\n\n async listRoles(): Promise<RoleData[]> {\n const docs = await this.collection.find().sort({ name: 1 }).toArray();\n return docs.map(doc => ({\n id: doc.id,\n name: doc.name,\n isAdmin: doc.isAdmin ?? false,\n defaultPermissions: doc.defaultPermissions ?? null,\n collectionPermissions: doc.collectionPermissions ?? null,\n config: doc.config ?? null\n }));\n }\n\n async createRole(data: CreateRoleData): Promise<RoleData> {\n const doc = {\n _id: data.id,\n id: data.id,\n name: data.name,\n isAdmin: data.isAdmin ?? false,\n defaultPermissions: data.defaultPermissions ?? null,\n collectionPermissions: data.collectionPermissions ?? null,\n config: data.config ?? null\n };\n await this.collection.insertOne(doc);\n return { ...doc } as RoleData;\n }\n\n async updateRole(id: string, data: Partial<Omit<RoleData, \"id\">>): Promise<RoleData | null> {\n await this.collection.updateOne({ id }, { $set: data });\n return this.getRoleById(id);\n }\n\n async deleteRole(id: string): Promise<void> {\n await this.collection.deleteOne({ id });\n await this.db.collection(\"rebase_user_roles\").deleteMany({ roleId: id });\n }\n}\n\nexport class MongoRefreshTokenService {\n constructor(private db: Db) {}\n\n private get collection() {\n return this.db.collection<MongoDoc>(\"rebase_refresh_tokens\");\n }\n\n async createToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {\n const safeUserAgent = userAgent || \"\";\n const safeIpAddress = ipAddress || \"\";\n\n await this.collection.deleteMany({\n userId,\n userAgent: safeUserAgent,\n ipAddress: safeIpAddress\n });\n\n await this.collection.insertOne({\n _id: new ObjectId().toString(),\n id: new ObjectId().toString(),\n userId,\n tokenHash,\n expiresAt,\n createdAt: new Date(),\n userAgent: safeUserAgent,\n ipAddress: safeIpAddress\n });\n }\n\n async findByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {\n const doc = await this.collection.findOne({ tokenHash });\n if (!doc) return null;\n return {\n id: doc.id,\n userId: doc.userId,\n tokenHash: doc.tokenHash,\n expiresAt: new Date(doc.expiresAt),\n createdAt: new Date(doc.createdAt),\n userAgent: doc.userAgent,\n ipAddress: doc.ipAddress\n };\n }\n\n async deleteByHash(tokenHash: string): Promise<void> {\n await this.collection.deleteOne({ tokenHash });\n }\n\n async deleteAllForUser(userId: string): Promise<void> {\n await this.collection.deleteMany({ userId });\n }\n\n async listForUser(userId: string): Promise<RefreshTokenInfo[]> {\n const docs = await this.collection.find({ userId }).sort({ createdAt: 1 }).toArray();\n return docs.map(doc => ({\n id: doc.id,\n userId: doc.userId,\n tokenHash: doc.tokenHash,\n expiresAt: new Date(doc.expiresAt),\n createdAt: new Date(doc.createdAt),\n userAgent: doc.userAgent,\n ipAddress: doc.ipAddress\n }));\n }\n\n async deleteById(id: string, userId: string): Promise<void> {\n await this.collection.deleteOne({ id, userId });\n }\n}\n\nexport class MongoPasswordResetTokenService {\n constructor(private db: Db) {}\n\n private get collection() {\n return this.db.collection<MongoDoc>(\"rebase_password_reset_tokens\");\n }\n\n async createToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {\n await this.collection.deleteMany({ userId, usedAt: null });\n\n await this.collection.insertOne({\n _id: new ObjectId().toString(),\n userId,\n tokenHash,\n expiresAt,\n usedAt: null\n });\n }\n\n async findValidByHash(tokenHash: string): Promise<{ userId: string; expiresAt: Date } | null> {\n const doc = await this.collection.findOne({ \n tokenHash, \n usedAt: null, \n expiresAt: { $gt: new Date() } \n });\n \n if (!doc) return null;\n \n return {\n userId: doc.userId,\n expiresAt: new Date(doc.expiresAt)\n };\n }\n\n async markAsUsed(tokenHash: string): Promise<void> {\n await this.collection.updateOne(\n { tokenHash },\n { $set: { usedAt: new Date() } }\n );\n }\n\n async deleteAllForUser(userId: string): Promise<void> {\n await this.collection.deleteMany({ userId });\n }\n\n async deleteExpired(): Promise<void> {\n await this.collection.deleteMany({ expiresAt: { $lt: new Date() } });\n }\n}\n\nexport class MongoTokenRepository implements TokenRepository {\n private refreshTokenService: MongoRefreshTokenService;\n private passwordResetTokenService: MongoPasswordResetTokenService;\n\n constructor(private db: Db) {\n this.refreshTokenService = new MongoRefreshTokenService(db);\n this.passwordResetTokenService = new MongoPasswordResetTokenService(db);\n }\n\n async createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {\n await this.refreshTokenService.createToken(userId, tokenHash, expiresAt, userAgent, ipAddress);\n }\n\n async findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {\n return this.refreshTokenService.findByHash(tokenHash);\n }\n\n async deleteRefreshToken(tokenHash: string): Promise<void> {\n await this.refreshTokenService.deleteByHash(tokenHash);\n }\n\n async deleteAllRefreshTokensForUser(userId: string): Promise<void> {\n await this.refreshTokenService.deleteAllForUser(userId);\n }\n\n async listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]> {\n return this.refreshTokenService.listForUser(userId);\n }\n\n async deleteRefreshTokenById(id: string, userId: string): Promise<void> {\n await this.refreshTokenService.deleteById(id, userId);\n }\n\n async createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {\n await this.passwordResetTokenService.createToken(userId, tokenHash, expiresAt);\n }\n\n async findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null> {\n return this.passwordResetTokenService.findValidByHash(tokenHash);\n }\n\n async markPasswordResetTokenUsed(tokenHash: string): Promise<void> {\n await this.passwordResetTokenService.markAsUsed(tokenHash);\n }\n\n async deleteAllPasswordResetTokensForUser(userId: string): Promise<void> {\n await this.passwordResetTokenService.deleteAllForUser(userId);\n }\n\n async deleteExpiredTokens(): Promise<void> {\n await this.passwordResetTokenService.deleteExpired();\n }\n}\n\nexport class MongoAuthRepository implements AuthRepository {\n private userService: MongoUserService;\n private roleService: MongoRoleService;\n private tokenRepository: MongoTokenRepository;\n\n constructor(private db: Db) {\n this.userService = new MongoUserService(db);\n this.roleService = new MongoRoleService(db);\n this.tokenRepository = new MongoTokenRepository(db);\n }\n\n async createUser(data: CreateUserData): Promise<UserData> {\n return this.userService.createUser(data);\n }\n\n async getUserById(id: string): Promise<UserData | null> {\n return this.userService.getUserById(id);\n }\n\n async getUserByEmail(email: string): Promise<UserData | null> {\n return this.userService.getUserByEmail(email);\n }\n\n async getUserByIdentity(provider: string, providerId: string): Promise<UserData | null> {\n return this.userService.getUserByIdentity(provider, providerId);\n }\n\n async getUserIdentities(userId: string): Promise<UserIdentityData[]> {\n return this.userService.getUserIdentities(userId);\n }\n\n async linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void> {\n return this.userService.linkUserIdentity(userId, provider, providerId, profileData);\n }\n\n async updateUser(id: string, data: Partial<Omit<CreateUserData, \"id\">>): Promise<UserData | null> {\n return this.userService.updateUser(id, data);\n }\n\n async deleteUser(id: string): Promise<void> {\n await this.userService.deleteUser(id);\n }\n\n async listUsers(): Promise<UserData[]> {\n return this.userService.listUsers();\n }\n\n async listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult> {\n return this.userService.listUsersPaginated(options);\n }\n\n async updatePassword(id: string, passwordHash: string): Promise<void> {\n await this.userService.updatePassword(id, passwordHash);\n }\n\n async setEmailVerified(id: string, verified: boolean): Promise<void> {\n await this.userService.setEmailVerified(id, verified);\n }\n\n async setVerificationToken(id: string, token: string | null): Promise<void> {\n await this.userService.setVerificationToken(id, token);\n }\n\n async getUserByVerificationToken(token: string): Promise<UserData | null> {\n return this.userService.getUserByVerificationToken(token);\n }\n\n async getUserRoles(userId: string): Promise<RoleData[]> {\n return this.userService.getUserRoles(userId);\n }\n\n async getUserRoleIds(userId: string): Promise<string[]> {\n return this.userService.getUserRoleIds(userId);\n }\n\n async setUserRoles(userId: string, roleIds: string[]): Promise<void> {\n await this.userService.setUserRoles(userId, roleIds);\n }\n\n async assignDefaultRole(userId: string, roleId: string): Promise<void> {\n await this.userService.assignDefaultRole(userId, roleId);\n }\n\n async getUserWithRoles(userId: string): Promise<{ user: UserData; roles: RoleData[] } | null> {\n return this.userService.getUserWithRoles(userId);\n }\n\n async getRoleById(id: string): Promise<RoleData | null> {\n return this.roleService.getRoleById(id);\n }\n\n async listRoles(): Promise<RoleData[]> {\n return this.roleService.listRoles();\n }\n\n async createRole(data: CreateRoleData): Promise<RoleData> {\n return this.roleService.createRole(data);\n }\n\n async updateRole(id: string, data: Partial<Omit<RoleData, \"id\">>): Promise<RoleData | null> {\n return this.roleService.updateRole(id, data);\n }\n\n async deleteRole(id: string): Promise<void> {\n await this.roleService.deleteRole(id);\n }\n\n async createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {\n await this.tokenRepository.createRefreshToken(userId, tokenHash, expiresAt, userAgent, ipAddress);\n }\n\n async findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {\n return this.tokenRepository.findRefreshTokenByHash(tokenHash);\n }\n\n async deleteRefreshToken(tokenHash: string): Promise<void> {\n await this.tokenRepository.deleteRefreshToken(tokenHash);\n }\n\n async deleteAllRefreshTokensForUser(userId: string): Promise<void> {\n await this.tokenRepository.deleteAllRefreshTokensForUser(userId);\n }\n\n async listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]> {\n return this.tokenRepository.listRefreshTokensForUser(userId);\n }\n\n async deleteRefreshTokenById(id: string, userId: string): Promise<void> {\n await this.tokenRepository.deleteRefreshTokenById(id, userId);\n }\n\n async createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {\n await this.tokenRepository.createPasswordResetToken(userId, tokenHash, expiresAt);\n }\n\n async findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null> {\n return this.tokenRepository.findValidPasswordResetToken(tokenHash);\n }\n\n async markPasswordResetTokenUsed(tokenHash: string): Promise<void> {\n await this.tokenRepository.markPasswordResetTokenUsed(tokenHash);\n }\n\n async deleteAllPasswordResetTokensForUser(userId: string): Promise<void> {\n await this.tokenRepository.deleteAllPasswordResetTokensForUser(userId);\n }\n\n async deleteExpiredTokens(): Promise<void> {\n await this.tokenRepository.deleteExpiredTokens();\n }\n}\n","import { Db, MongoClient } from \"mongodb\";\nimport {\n BackendBootstrapper,\n InitializedDriver,\n BootstrappedAuth,\n DatabaseAdmin,\n RealtimeProvider,\n DataDriver,\n EntityCollection\n} from \"@rebasepro/types\";\nimport { MongoDriver } from \"./services/MongoDriver\";\nimport { MongoRealtimeService } from \"./services/MongoRealtimeService\";\nimport { MongoCollectionRegistry } from \"./factory\";\nimport { MongoAuthRepository, MongoUserService, MongoRoleService } from \"./auth/services\";\n\nexport interface MongoDriverConfig {\n connection: Db;\n client: MongoClient;\n}\n\nexport interface MongoDriverInternals {\n db: Db;\n client: MongoClient;\n registry: MongoCollectionRegistry;\n realtimeService: MongoRealtimeService;\n driver: MongoDriver;\n}\n\nexport function createMongoBootstrapper(mongoConfig: MongoDriverConfig): BackendBootstrapper {\n // Cached admin object, set during getAdmin() and used by initializeWebsockets\n let cachedAdmin: DatabaseAdmin | undefined;\n\n return {\n type: \"mongodb\",\n\n async initializeDriver(config: unknown): Promise<InitializedDriver> {\n const { collections } = config as { collections?: EntityCollection[] };\n\n const registry = new MongoCollectionRegistry();\n if (collections) {\n collections.forEach(collection => registry.register(collection));\n }\n\n const db = mongoConfig.connection;\n const client = mongoConfig.client;\n\n // Verify connection\n try {\n await db.command({ ping: 1 });\n } catch (err) {\n console.error(\"❌ Failed to connect to MongoDB:\", err);\n }\n\n const realtimeService = new MongoRealtimeService(db);\n const driver = new MongoDriver(db, realtimeService);\n\n const internals: MongoDriverInternals = {\n db,\n client,\n registry,\n realtimeService,\n driver\n };\n\n return {\n driver,\n realtimeProvider: realtimeService,\n collectionRegistry: registry,\n internals\n };\n },\n\n async initializeAuth(config: unknown, driverResult: InitializedDriver): Promise<BootstrappedAuth | undefined> {\n const internals = driverResult.internals as MongoDriverInternals;\n const db = internals.db;\n\n const { ensureAuthCollectionsExist } = await import(\"./auth/ensure-collections\");\n await ensureAuthCollectionsExist(db);\n\n // @ts-ignore\n const { createEmailService } = await import(\"@rebasepro/server-core\");\n const authConfig = config as { email?: any } | undefined;\n let emailService: any;\n if (authConfig?.email) {\n emailService = createEmailService(authConfig.email);\n }\n\n const userService = new MongoUserService(db);\n const roleService = new MongoRoleService(db);\n const authRepository = new MongoAuthRepository(db);\n\n return {\n userService,\n roleService,\n authRepository,\n emailService\n };\n },\n\n async initializeHistory(config: unknown, driverResult: InitializedDriver): Promise<{ historyService: any } | undefined> {\n const historyConfig = config as { retention?: number } | undefined;\n if (!historyConfig) return undefined;\n\n const internals = driverResult.internals as MongoDriverInternals;\n const db = internals.db;\n\n const { ensureHistoryCollectionExists } = await import(\"./history/ensure-history-collection\");\n await ensureHistoryCollectionExists(db);\n\n const { MongoHistoryService } = await import(\"./services/MongoHistoryService\");\n \n const retention = typeof historyConfig === \"object\" && historyConfig !== null ? historyConfig.retention : undefined;\n const historyService = new MongoHistoryService(db, retention ? { ttlDays: retention } : undefined);\n\n return { historyService };\n },\n\n async initializeRealtime(_config: unknown, driverResult: InitializedDriver): Promise<RealtimeProvider | undefined> {\n const internals = driverResult.internals as MongoDriverInternals;\n return internals.realtimeService;\n },\n\n getAdmin(driverResult: InitializedDriver): DatabaseAdmin | undefined {\n const internals = driverResult.internals as MongoDriverInternals;\n const db = internals.db;\n\n const admin: DatabaseAdmin = {\n async executeAggregate(pipeline: Record<string, unknown>[]) {\n const firstStage = pipeline[0];\n const collName = (firstStage as { $from?: string })?.$from ?? \"__admin__\";\n const cursor = db.collection(collName).aggregate(pipeline);\n return await cursor.toArray() as Record<string, unknown>[];\n },\n async fetchCollectionStats(collectionName: string) {\n const stats = await db.command({ collStats: collectionName }) as { count: number; size: number };\n return { count: stats.count, sizeBytes: stats.size };\n },\n async fetchUnmappedTables(mappedPaths?: string[]) {\n const allCollections = await db.listCollections().toArray();\n const names = allCollections.map(c => c.name).filter(n => !n.startsWith(\"system.\"));\n if (!mappedPaths || mappedPaths.length === 0) return names;\n const mappedSet = new Set(mappedPaths.map(p => p.toLowerCase()));\n return names.filter(n => !mappedSet.has(n.toLowerCase()));\n },\n async fetchTableMetadata(collectionName: string) {\n const sample = await db.collection(collectionName).findOne();\n if (!sample) return { columns: [], foreignKeys: [], junctions: [], policies: [] };\n const columns = Object.entries(sample).map(([key, value]) => ({\n column_name: key,\n data_type: typeof value,\n udt_name: typeof value,\n is_nullable: \"YES\",\n column_default: null,\n character_maximum_length: null\n }));\n return { columns, foreignKeys: [], junctions: [], policies: [] };\n }\n };\n\n cachedAdmin = admin;\n return admin;\n },\n\n mountRoutes() {},\n\n async initializeWebsockets(server: unknown, realtimeService: RealtimeProvider, driver: DataDriver, config?: unknown): Promise<void> {\n const { createMongoWebSocket } = await import(\"./websocket\");\n createMongoWebSocket(\n server as import(\"http\").Server,\n realtimeService as MongoRealtimeService,\n driver as MongoDriver,\n config as Record<string, unknown> | undefined,\n cachedAdmin\n );\n }\n };\n}\n"],"names":["MongoHistoryService"],"mappings":"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"}
|