@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,519 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
|
|
3
|
+
import { App, BSON } from "realm-web";
|
|
4
|
+
import { DataDriver, DeleteEntityProps, Entity, EntityCollection, EntityReference, EntityValues, FetchCollectionProps, FetchEntityProps, FilterValues, ListenCollectionProps, ListenEntityProps, PropertyConfig, SaveEntityProps, WhereFilterOp } from "@rebasepro/types";
|
|
5
|
+
import { addValueAtIndex, getEntityIndex, removeValueAtIndex, replaceValueAtIndex, updateValueAtIndex } from "./utils";
|
|
6
|
+
|
|
7
|
+
type ChangeEvent = any;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export interface UseMongoDriverProps {
|
|
13
|
+
app: App,
|
|
14
|
+
cluster: string,
|
|
15
|
+
database: string,
|
|
16
|
+
propertyConfigs?: Record<string, PropertyConfig>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const rebaseToMongoDB: Record<WhereFilterOp, string> = {
|
|
20
|
+
"<": "$lt",
|
|
21
|
+
"<=": "$lte",
|
|
22
|
+
"==": "$eq",
|
|
23
|
+
"!=": "$ne",
|
|
24
|
+
">=": "$gte",
|
|
25
|
+
">": "$gt",
|
|
26
|
+
"array-contains": "$eq",
|
|
27
|
+
"array-contains-any": "in",
|
|
28
|
+
"in": "$in",
|
|
29
|
+
"not-in": "$nin" // Please note the semantic difference
|
|
30
|
+
// "array-contains-any": ??? // There's no MongoDB equivalent
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Use this hook to build a {@link DataDriver} based on Firestore
|
|
35
|
+
* @param firebaseApp
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
export function useMongoDriver({
|
|
39
|
+
app,
|
|
40
|
+
cluster,
|
|
41
|
+
database
|
|
42
|
+
}: UseMongoDriverProps): DataDriver {
|
|
43
|
+
|
|
44
|
+
const buildQuery = useCallback((
|
|
45
|
+
filter: FilterValues<any> | undefined,
|
|
46
|
+
searchString?: string,
|
|
47
|
+
orderBy?: string,
|
|
48
|
+
order?: "desc" | "asc",
|
|
49
|
+
limit?: number): [any, any] => {
|
|
50
|
+
|
|
51
|
+
const queryParams: any = {};
|
|
52
|
+
if (filter) {
|
|
53
|
+
Object.entries(filter).forEach(([key, filterParameter]) => {
|
|
54
|
+
const [op, value] = filterParameter as [WhereFilterOp, any];
|
|
55
|
+
const opMongo = rebaseToMongoDB[op];
|
|
56
|
+
queryParams[key] = { [opMongo]: value };
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// if (searchString) {
|
|
61
|
+
// queryParams['$text'] = { $search: searchString };
|
|
62
|
+
// }
|
|
63
|
+
|
|
64
|
+
const options: any = {};
|
|
65
|
+
if (orderBy && order) {
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
options["sort"] = { [orderBy]: (order === "desc" ? -1 : 1) };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (limit) {
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
options["limit"] = limit;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return [queryParams, options];
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
const fetchCollection = useCallback(async <M extends Record<string, any>>({
|
|
79
|
+
path,
|
|
80
|
+
collection,
|
|
81
|
+
filter,
|
|
82
|
+
limit,
|
|
83
|
+
searchString,
|
|
84
|
+
orderBy,
|
|
85
|
+
order
|
|
86
|
+
}: FetchCollectionProps<M>
|
|
87
|
+
): Promise<Entity<M>[]> => {
|
|
88
|
+
|
|
89
|
+
if (!app?.currentUser)
|
|
90
|
+
throw Error("useMongoDriver app not initialised");
|
|
91
|
+
|
|
92
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
93
|
+
const mongoCollection = mdb.db(database).collection(path);
|
|
94
|
+
|
|
95
|
+
const [queryParams, options] = buildQuery(filter, searchString, orderBy, order, limit);
|
|
96
|
+
|
|
97
|
+
if (searchString) {
|
|
98
|
+
const res = await mongoCollection.aggregate([
|
|
99
|
+
{
|
|
100
|
+
$search: {
|
|
101
|
+
"text": {
|
|
102
|
+
"query": searchString,
|
|
103
|
+
"path": { "wildcard": "*" },
|
|
104
|
+
"fuzzy": {}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
$match: queryParams
|
|
111
|
+
}
|
|
112
|
+
]);
|
|
113
|
+
return res.map((doc: any) => mongoToEntity(doc, path));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const fetchedDocs = await mongoCollection.find(queryParams, options);
|
|
117
|
+
return fetchedDocs.map((doc: any) => mongoToEntity(doc, path));
|
|
118
|
+
}, [app, buildQuery, cluster, database]);
|
|
119
|
+
|
|
120
|
+
const fetchEntity = useCallback(async <M extends Record<string, any>>({
|
|
121
|
+
path,
|
|
122
|
+
entityId,
|
|
123
|
+
collection
|
|
124
|
+
}: FetchEntityProps<M>
|
|
125
|
+
): Promise<Entity<M> | undefined> => {
|
|
126
|
+
if (!app?.currentUser) throw Error("useMongoDriver app not initialised");
|
|
127
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
128
|
+
const mongoCollection = mdb.db(database).collection(path);
|
|
129
|
+
const doc = await mongoCollection
|
|
130
|
+
.findOne({
|
|
131
|
+
_id: new BSON.ObjectId(entityId)
|
|
132
|
+
});
|
|
133
|
+
if (!doc) return undefined;
|
|
134
|
+
return mongoToEntity(doc, path);
|
|
135
|
+
}, [app.currentUser, cluster, database]);
|
|
136
|
+
|
|
137
|
+
const saveEntity = useCallback(async <M extends Record<string, any>>(
|
|
138
|
+
{
|
|
139
|
+
path,
|
|
140
|
+
entityId,
|
|
141
|
+
values,
|
|
142
|
+
collection,
|
|
143
|
+
status
|
|
144
|
+
}: SaveEntityProps<M>): Promise<Entity<M>> => {
|
|
145
|
+
if (!app?.currentUser) throw Error("useMongoDriver app not initialised");
|
|
146
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
147
|
+
const mongoCollection = mdb.db(database).collection(path);
|
|
148
|
+
const mongoValues = values;
|
|
149
|
+
if (status === "existing") {
|
|
150
|
+
await mongoCollection
|
|
151
|
+
.updateOne({
|
|
152
|
+
_id: new BSON.ObjectId(entityId)
|
|
153
|
+
}, {
|
|
154
|
+
$set: mongoValues
|
|
155
|
+
});
|
|
156
|
+
return {
|
|
157
|
+
id: entityId as string,
|
|
158
|
+
path: path,
|
|
159
|
+
values: convertFromMongoValues(values) as M
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const res = await mongoCollection
|
|
163
|
+
.insertOne({
|
|
164
|
+
_id: new BSON.ObjectId(entityId),
|
|
165
|
+
...mongoValues
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
id: res.insertedId.toString(),
|
|
169
|
+
path: path,
|
|
170
|
+
values: values as M
|
|
171
|
+
};
|
|
172
|
+
}, [app.currentUser, cluster, database]);
|
|
173
|
+
|
|
174
|
+
const listenEntity = useCallback(<M extends Record<string, any>>(
|
|
175
|
+
{
|
|
176
|
+
path,
|
|
177
|
+
entityId,
|
|
178
|
+
collection,
|
|
179
|
+
onUpdate,
|
|
180
|
+
onError
|
|
181
|
+
}: ListenEntityProps<M>): () => void => {
|
|
182
|
+
|
|
183
|
+
fetchEntity({
|
|
184
|
+
path,
|
|
185
|
+
entityId,
|
|
186
|
+
collection
|
|
187
|
+
}).then((entity) => {
|
|
188
|
+
if (entity)
|
|
189
|
+
onUpdate(entity);
|
|
190
|
+
if (!entity)
|
|
191
|
+
onError?.(new Error("Entity not found"));
|
|
192
|
+
});
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
194
|
+
return () => {
|
|
195
|
+
}
|
|
196
|
+
}, [fetchEntity]);
|
|
197
|
+
|
|
198
|
+
const listenCollection = useCallback(<M extends Record<string, any>>(
|
|
199
|
+
{
|
|
200
|
+
path,
|
|
201
|
+
collection,
|
|
202
|
+
filter,
|
|
203
|
+
limit,
|
|
204
|
+
startAfter,
|
|
205
|
+
searchString,
|
|
206
|
+
orderBy,
|
|
207
|
+
order,
|
|
208
|
+
onUpdate,
|
|
209
|
+
onError
|
|
210
|
+
}: ListenCollectionProps<M>
|
|
211
|
+
): () => void => {
|
|
212
|
+
|
|
213
|
+
if (!app?.currentUser) throw Error("useMongoDriver app not initialised");
|
|
214
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
215
|
+
const mongoCollection = mdb.db(database).collection(path);
|
|
216
|
+
|
|
217
|
+
let currentEntities: Entity<M>[] = [];
|
|
218
|
+
|
|
219
|
+
const updateCurrentEntities = (entities: Entity<M>[]) => {
|
|
220
|
+
currentEntities = entities;
|
|
221
|
+
onUpdate(entities);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let stream: AsyncGenerator<ChangeEvent> | undefined = undefined;
|
|
225
|
+
|
|
226
|
+
fetchCollection({
|
|
227
|
+
path,
|
|
228
|
+
collection,
|
|
229
|
+
filter,
|
|
230
|
+
limit,
|
|
231
|
+
startAfter,
|
|
232
|
+
searchString,
|
|
233
|
+
orderBy,
|
|
234
|
+
order
|
|
235
|
+
}).then(updateCurrentEntities).catch(onError)
|
|
236
|
+
|
|
237
|
+
const onDocDelete = (change: ChangeEvent) => {
|
|
238
|
+
const idx = getEntityIndex(currentEntities, { id: change.documentKey._id });
|
|
239
|
+
if (idx && idx >= 0) {
|
|
240
|
+
updateCurrentEntities(removeValueAtIndex(currentEntities, idx));
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const onDocInsert = (change: ChangeEvent) => {
|
|
244
|
+
const entity = mongoToEntity(change.fullDocument, path);
|
|
245
|
+
const idx =
|
|
246
|
+
getEntityIndex(currentEntities, entity) ?? currentEntities.length;
|
|
247
|
+
if (idx === currentEntities.length) {
|
|
248
|
+
const updatedEntities = addValueAtIndex(currentEntities, idx, entity);
|
|
249
|
+
updateCurrentEntities(updatedEntities);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
const onDocReplace = (change: ChangeEvent) => {
|
|
253
|
+
const entity = mongoToEntity(change.fullDocument, path);
|
|
254
|
+
const idx = getEntityIndex(currentEntities, entity);
|
|
255
|
+
if (idx === null) return;
|
|
256
|
+
updateCurrentEntities(replaceValueAtIndex(currentEntities, idx, entity));
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const onDocUpdate = (change: ChangeEvent) => {
|
|
260
|
+
const entity = mongoToEntity(change.fullDocument, path);
|
|
261
|
+
const idx = getEntityIndex(currentEntities, entity);
|
|
262
|
+
if (idx === null) return;
|
|
263
|
+
updateCurrentEntities(updateValueAtIndex(currentEntities, idx, () => {
|
|
264
|
+
return entity;
|
|
265
|
+
}));
|
|
266
|
+
};
|
|
267
|
+
const watchCollection = async () => {
|
|
268
|
+
const [queryParams, options] = buildQuery(filter, searchString, orderBy, order, limit);
|
|
269
|
+
stream = mongoCollection.watch(queryParams);
|
|
270
|
+
if (!stream) return;
|
|
271
|
+
for await (const change of stream) {
|
|
272
|
+
switch (change.operationType) {
|
|
273
|
+
case "insert": {
|
|
274
|
+
onDocInsert(change);
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
case "update": {
|
|
278
|
+
onDocUpdate(change);
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case "replace": {
|
|
282
|
+
onDocReplace(change);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
case "delete": {
|
|
286
|
+
onDocDelete(change);
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
default: {
|
|
290
|
+
// change.operationType will always be one of the specified cases, so we should never hit this default
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Invalid change operation type: ${change.operationType}`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
watchCollection();
|
|
300
|
+
|
|
301
|
+
return () => {
|
|
302
|
+
// @ts-ignore
|
|
303
|
+
stream?.return();
|
|
304
|
+
}
|
|
305
|
+
}, [app.currentUser, cluster, database, fetchCollection]);
|
|
306
|
+
|
|
307
|
+
const generateEntityId = useCallback((path: string): string => {
|
|
308
|
+
return new BSON.ObjectId().toString();
|
|
309
|
+
}, []);
|
|
310
|
+
|
|
311
|
+
const deleteEntity = useCallback(async <M extends Record<string, any>>(
|
|
312
|
+
{
|
|
313
|
+
entity
|
|
314
|
+
}: DeleteEntityProps<M>
|
|
315
|
+
): Promise<void> => {
|
|
316
|
+
if (!app?.currentUser) throw Error("useMongoDriver app not initialised");
|
|
317
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
318
|
+
const mongoCollection = mdb.db(database).collection(entity.path);
|
|
319
|
+
const res = await mongoCollection
|
|
320
|
+
.deleteOne({
|
|
321
|
+
_id: new BSON.ObjectId(entity.id)
|
|
322
|
+
});
|
|
323
|
+
if (res.deletedCount === 0) {
|
|
324
|
+
console.error("No entities were deleted", res);
|
|
325
|
+
throw Error("No entities were deleted");
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
}, [app.currentUser, cluster, database]);
|
|
329
|
+
|
|
330
|
+
const countEntities = useCallback(async (props: {
|
|
331
|
+
path: string,
|
|
332
|
+
collection: EntityCollection<any>
|
|
333
|
+
onCountUpdate?: (count: number) => void
|
|
334
|
+
}): Promise<number> => {
|
|
335
|
+
if (!app?.currentUser) throw Error("useMongoDriver app not initialised");
|
|
336
|
+
const mdb = app.currentUser.mongoClient(cluster);
|
|
337
|
+
const mongoCollection = mdb.db(database).collection(props.path);
|
|
338
|
+
return mongoCollection.count();
|
|
339
|
+
}, [app.currentUser, cluster, database]);
|
|
340
|
+
|
|
341
|
+
const checkUniqueField = useCallback((
|
|
342
|
+
path: string,
|
|
343
|
+
name: string,
|
|
344
|
+
value: any,
|
|
345
|
+
entityId?: string
|
|
346
|
+
): Promise<boolean> => {
|
|
347
|
+
throw Error("checkUniqueField not implemented");
|
|
348
|
+
}, []);
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
key: "mongodb",
|
|
352
|
+
cmsToDelegateModel(data: any): any {
|
|
353
|
+
return valuesToMongoValues(data);
|
|
354
|
+
},
|
|
355
|
+
delegateToCMSModel(data: any): any {
|
|
356
|
+
return convertFromMongoValue(data);
|
|
357
|
+
},
|
|
358
|
+
currentTime(): any {
|
|
359
|
+
return new Date();
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Check if the given property is unique in the given collection
|
|
364
|
+
* @param path Collection path
|
|
365
|
+
* @param name of the property
|
|
366
|
+
* @param value
|
|
367
|
+
* @param property
|
|
368
|
+
* @param entityId
|
|
369
|
+
* @return `true` if there are no other fields besides the given entity
|
|
370
|
+
*
|
|
371
|
+
*/
|
|
372
|
+
checkUniqueField: checkUniqueField,
|
|
373
|
+
|
|
374
|
+
countEntities: countEntities,
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Delete an entity
|
|
378
|
+
* @param entity
|
|
379
|
+
* @param collection
|
|
380
|
+
*
|
|
381
|
+
*/
|
|
382
|
+
deleteEntity: deleteEntity,
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Fetch entities in a Firestore path
|
|
386
|
+
* @param path
|
|
387
|
+
* @param collection
|
|
388
|
+
* @param filter
|
|
389
|
+
* @param limit
|
|
390
|
+
* @param startAfter
|
|
391
|
+
* @param searchString
|
|
392
|
+
* @param orderBy
|
|
393
|
+
* @param order
|
|
394
|
+
* @return Function to cancel subscription
|
|
395
|
+
* @see useCollectionFetch if you need this functionality implemented as a hook
|
|
396
|
+
*
|
|
397
|
+
*/
|
|
398
|
+
fetchCollection: fetchCollection,
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Retrieve an entity given a path and a collection
|
|
402
|
+
* @param path
|
|
403
|
+
* @param entityId
|
|
404
|
+
* @param collection
|
|
405
|
+
*
|
|
406
|
+
*/
|
|
407
|
+
fetchEntity: fetchEntity,
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Listen to a entities in a given path
|
|
411
|
+
* @param path
|
|
412
|
+
* @param collection
|
|
413
|
+
* @param onError
|
|
414
|
+
* @param filter
|
|
415
|
+
* @param limit
|
|
416
|
+
* @param startAfter
|
|
417
|
+
* @param searchString
|
|
418
|
+
* @param orderBy
|
|
419
|
+
* @param order
|
|
420
|
+
* @param onUpdate
|
|
421
|
+
* @return Function to cancel subscription
|
|
422
|
+
* @see useCollectionFetch if you need this functionality implemented as a hook
|
|
423
|
+
*
|
|
424
|
+
*/
|
|
425
|
+
listenCollection: listenCollection,
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
*
|
|
429
|
+
* @param path
|
|
430
|
+
* @param entityId
|
|
431
|
+
* @param collection
|
|
432
|
+
* @param onUpdate
|
|
433
|
+
* @param onError
|
|
434
|
+
* @return Function to cancel subscription
|
|
435
|
+
*
|
|
436
|
+
*/
|
|
437
|
+
listenEntity: listenEntity,
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Save entity to the specified path. Note that Firestore does not allow
|
|
441
|
+
* undefined values.
|
|
442
|
+
* @param path
|
|
443
|
+
* @param entityId
|
|
444
|
+
* @param values
|
|
445
|
+
* @param schemaId
|
|
446
|
+
* @param collection
|
|
447
|
+
* @param status
|
|
448
|
+
*
|
|
449
|
+
*/
|
|
450
|
+
saveEntity: saveEntity
|
|
451
|
+
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const mongoToEntity = (doc: any, path: string): Entity<any> => {
|
|
457
|
+
const {
|
|
458
|
+
_id,
|
|
459
|
+
...data
|
|
460
|
+
} = doc;
|
|
461
|
+
return {
|
|
462
|
+
id: _id.toString(),
|
|
463
|
+
path: path,
|
|
464
|
+
values: convertFromMongoValues(data)
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const convertFromMongoValues = (values: object): object => {
|
|
469
|
+
return Object
|
|
470
|
+
.entries(values)
|
|
471
|
+
.map(([k, v]) => ({ [k]: convertFromMongoValue(v) }))
|
|
472
|
+
.reduce((a, b) => ({ ...a,
|
|
473
|
+
...b }), {});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function convertFromMongoValue(value: unknown): any {
|
|
477
|
+
|
|
478
|
+
if (typeof value !== "object" || value === null) return value;
|
|
479
|
+
if (Array.isArray(value)) return value.map(convertFromMongoValue);
|
|
480
|
+
|
|
481
|
+
if (typeof value === "object") {
|
|
482
|
+
if (value instanceof Date) {
|
|
483
|
+
return value;
|
|
484
|
+
}
|
|
485
|
+
if ("path" in value && "id" in value && typeof value.path === "string") {
|
|
486
|
+
return new EntityReference({ id: String(value.id),
|
|
487
|
+
path: value.path });
|
|
488
|
+
}
|
|
489
|
+
return convertFromMongoValues(value);
|
|
490
|
+
}
|
|
491
|
+
return value;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function valuesToMongoValues(values: EntityValues<any>) {
|
|
495
|
+
return Object.entries(values)
|
|
496
|
+
.map(([key, value]) => ({ [key]: valueToMongoValue(value) }))
|
|
497
|
+
.reduce((a, b) => ({ ...a,
|
|
498
|
+
...b }), {});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function valueToMongoValue(value: any): any {
|
|
502
|
+
if (value === null)
|
|
503
|
+
return null;
|
|
504
|
+
if (value.isEntityReference && value.isEntityReference()) {
|
|
505
|
+
return {
|
|
506
|
+
id: new BSON.ObjectId(value.id),
|
|
507
|
+
path: value.path
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
if (typeof value !== "object") return value;
|
|
511
|
+
if (Array.isArray(value)) return value.map(valueToMongoValue);
|
|
512
|
+
if (typeof value === "object") {
|
|
513
|
+
if (value instanceof Date) {
|
|
514
|
+
return value;
|
|
515
|
+
}
|
|
516
|
+
return valuesToMongoValues(value);
|
|
517
|
+
}
|
|
518
|
+
return value;
|
|
519
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function getEntityIndex(entities: { id: string | number }[], entity: { id: string | number }): number | null {
|
|
2
|
+
const idx = entities.findIndex(e => e.id === entity.id);
|
|
3
|
+
return idx === -1 ? null : idx;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function removeValueAtIndex<T>(arr: T[], index: number): T[] {
|
|
7
|
+
const copy = [...arr];
|
|
8
|
+
copy.splice(index, 1);
|
|
9
|
+
return copy;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function addValueAtIndex<T>(arr: T[], index: number, value: T): T[] {
|
|
13
|
+
const copy = [...arr];
|
|
14
|
+
copy.splice(index, 0, value);
|
|
15
|
+
return copy;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function replaceValueAtIndex<T>(arr: T[], index: number, value: T): T[] {
|
|
19
|
+
const copy = [...arr];
|
|
20
|
+
copy.splice(index, 1, value);
|
|
21
|
+
return copy;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function updateValueAtIndex<T>(arr: T[], index: number, updater: (val: T) => T): T[] {
|
|
25
|
+
const copy = [...arr];
|
|
26
|
+
copy[index] = updater(copy[index]);
|
|
27
|
+
return copy;
|
|
28
|
+
}
|