@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.
Files changed (286) hide show
  1. package/LICENSE +6 -0
  2. package/dist/ensure-collections-CNrcwVgY.js +74 -0
  3. package/dist/ensure-collections-CNrcwVgY.js.map +1 -0
  4. package/dist/ensure-history-collection-DBIiwmCm.js +15 -0
  5. package/dist/ensure-history-collection-DBIiwmCm.js.map +1 -0
  6. package/dist/index.es.js +1734 -0
  7. package/dist/index.es.js.map +1 -0
  8. package/dist/index.umd.js +2043 -0
  9. package/dist/index.umd.js.map +1 -0
  10. package/dist/server-core/src/api/ast-schema-editor.d.ts +22 -0
  11. package/dist/server-core/src/api/ast-schema-editor.d.ts.map +1 -0
  12. package/dist/server-core/src/api/errors.d.ts +36 -0
  13. package/dist/server-core/src/api/errors.d.ts.map +1 -0
  14. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +36 -0
  15. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts.map +1 -0
  16. package/dist/server-core/src/api/graphql/index.d.ts +2 -0
  17. package/dist/server-core/src/api/graphql/index.d.ts.map +1 -0
  18. package/dist/server-core/src/api/index.d.ts +10 -0
  19. package/dist/server-core/src/api/index.d.ts.map +1 -0
  20. package/dist/server-core/src/api/openapi-generator.d.ts +17 -0
  21. package/dist/server-core/src/api/openapi-generator.d.ts.map +1 -0
  22. package/dist/server-core/src/api/rest/api-generator.d.ts +65 -0
  23. package/dist/server-core/src/api/rest/api-generator.d.ts.map +1 -0
  24. package/dist/server-core/src/api/rest/index.d.ts +2 -0
  25. package/dist/server-core/src/api/rest/index.d.ts.map +1 -0
  26. package/dist/server-core/src/api/rest/query-parser.d.ts +10 -0
  27. package/dist/server-core/src/api/rest/query-parser.d.ts.map +1 -0
  28. package/dist/server-core/src/api/schema-editor-routes.d.ts +4 -0
  29. package/dist/server-core/src/api/schema-editor-routes.d.ts.map +1 -0
  30. package/dist/server-core/src/api/server.d.ts +41 -0
  31. package/dist/server-core/src/api/server.d.ts.map +1 -0
  32. package/dist/server-core/src/api/types.d.ts +91 -0
  33. package/dist/server-core/src/api/types.d.ts.map +1 -0
  34. package/dist/server-core/src/auth/admin-routes.d.ts +17 -0
  35. package/dist/server-core/src/auth/admin-routes.d.ts.map +1 -0
  36. package/dist/server-core/src/auth/apple-oauth.d.ts +31 -0
  37. package/dist/server-core/src/auth/apple-oauth.d.ts.map +1 -0
  38. package/dist/server-core/src/auth/bitbucket-oauth.d.ts +12 -0
  39. package/dist/server-core/src/auth/bitbucket-oauth.d.ts.map +1 -0
  40. package/dist/server-core/src/auth/discord-oauth.d.ts +15 -0
  41. package/dist/server-core/src/auth/discord-oauth.d.ts.map +1 -0
  42. package/dist/server-core/src/auth/facebook-oauth.d.ts +15 -0
  43. package/dist/server-core/src/auth/facebook-oauth.d.ts.map +1 -0
  44. package/dist/server-core/src/auth/github-oauth.d.ts +16 -0
  45. package/dist/server-core/src/auth/github-oauth.d.ts.map +1 -0
  46. package/dist/server-core/src/auth/gitlab-oauth.d.ts +14 -0
  47. package/dist/server-core/src/auth/gitlab-oauth.d.ts.map +1 -0
  48. package/dist/server-core/src/auth/google-oauth.d.ts +15 -0
  49. package/dist/server-core/src/auth/google-oauth.d.ts.map +1 -0
  50. package/dist/server-core/src/auth/index.d.ts +24 -0
  51. package/dist/server-core/src/auth/index.d.ts.map +1 -0
  52. package/dist/server-core/src/auth/interfaces.d.ts +310 -0
  53. package/dist/server-core/src/auth/interfaces.d.ts.map +1 -0
  54. package/dist/server-core/src/auth/jwt.d.ts +44 -0
  55. package/dist/server-core/src/auth/jwt.d.ts.map +1 -0
  56. package/dist/server-core/src/auth/linkedin-oauth.d.ts +19 -0
  57. package/dist/server-core/src/auth/linkedin-oauth.d.ts.map +1 -0
  58. package/dist/server-core/src/auth/microsoft-oauth.d.ts +17 -0
  59. package/dist/server-core/src/auth/microsoft-oauth.d.ts.map +1 -0
  60. package/dist/server-core/src/auth/middleware.d.ts +82 -0
  61. package/dist/server-core/src/auth/middleware.d.ts.map +1 -0
  62. package/dist/server-core/src/auth/password.d.ts +23 -0
  63. package/dist/server-core/src/auth/password.d.ts.map +1 -0
  64. package/dist/server-core/src/auth/rate-limiter.d.ts +32 -0
  65. package/dist/server-core/src/auth/rate-limiter.d.ts.map +1 -0
  66. package/dist/server-core/src/auth/routes.d.ts +28 -0
  67. package/dist/server-core/src/auth/routes.d.ts.map +1 -0
  68. package/dist/server-core/src/auth/slack-oauth.d.ts +13 -0
  69. package/dist/server-core/src/auth/slack-oauth.d.ts.map +1 -0
  70. package/dist/server-core/src/auth/spotify-oauth.d.ts +13 -0
  71. package/dist/server-core/src/auth/spotify-oauth.d.ts.map +1 -0
  72. package/dist/server-core/src/auth/twitter-oauth.d.ts +19 -0
  73. package/dist/server-core/src/auth/twitter-oauth.d.ts.map +1 -0
  74. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +14 -0
  75. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts.map +1 -0
  76. package/dist/server-core/src/collections/loader.d.ts +6 -0
  77. package/dist/server-core/src/collections/loader.d.ts.map +1 -0
  78. package/dist/server-core/src/cron/cron-loader.d.ts +18 -0
  79. package/dist/server-core/src/cron/cron-loader.d.ts.map +1 -0
  80. package/dist/server-core/src/cron/cron-routes.d.ts +15 -0
  81. package/dist/server-core/src/cron/cron-routes.d.ts.map +1 -0
  82. package/dist/server-core/src/cron/cron-scheduler.d.ts +62 -0
  83. package/dist/server-core/src/cron/cron-scheduler.d.ts.map +1 -0
  84. package/dist/server-core/src/cron/cron-store.d.ts +33 -0
  85. package/dist/server-core/src/cron/cron-store.d.ts.map +1 -0
  86. package/dist/server-core/src/cron/index.d.ts +7 -0
  87. package/dist/server-core/src/cron/index.d.ts.map +1 -0
  88. package/dist/server-core/src/db/interfaces.d.ts +19 -0
  89. package/dist/server-core/src/db/interfaces.d.ts.map +1 -0
  90. package/dist/server-core/src/email/index.d.ts +7 -0
  91. package/dist/server-core/src/email/index.d.ts.map +1 -0
  92. package/dist/server-core/src/email/smtp-email-service.d.ts +26 -0
  93. package/dist/server-core/src/email/smtp-email-service.d.ts.map +1 -0
  94. package/dist/server-core/src/email/templates.d.ts +43 -0
  95. package/dist/server-core/src/email/templates.d.ts.map +1 -0
  96. package/dist/server-core/src/email/types.d.ts +108 -0
  97. package/dist/server-core/src/email/types.d.ts.map +1 -0
  98. package/dist/server-core/src/functions/function-loader.d.ts +18 -0
  99. package/dist/server-core/src/functions/function-loader.d.ts.map +1 -0
  100. package/dist/server-core/src/functions/function-routes.d.ts +11 -0
  101. package/dist/server-core/src/functions/function-routes.d.ts.map +1 -0
  102. package/dist/server-core/src/functions/index.d.ts +4 -0
  103. package/dist/server-core/src/functions/index.d.ts.map +1 -0
  104. package/dist/server-core/src/history/history-routes.d.ts +24 -0
  105. package/dist/server-core/src/history/history-routes.d.ts.map +1 -0
  106. package/dist/server-core/src/history/index.d.ts +2 -0
  107. package/dist/server-core/src/history/index.d.ts.map +1 -0
  108. package/dist/server-core/src/index.d.ts +30 -0
  109. package/dist/server-core/src/index.d.ts.map +1 -0
  110. package/dist/server-core/src/init.d.ts +160 -0
  111. package/dist/server-core/src/init.d.ts.map +1 -0
  112. package/dist/server-core/src/serve-spa.d.ts +31 -0
  113. package/dist/server-core/src/serve-spa.d.ts.map +1 -0
  114. package/dist/server-core/src/services/driver-registry.d.ts +79 -0
  115. package/dist/server-core/src/services/driver-registry.d.ts.map +1 -0
  116. package/dist/server-core/src/singleton.d.ts +36 -0
  117. package/dist/server-core/src/singleton.d.ts.map +1 -0
  118. package/dist/server-core/src/storage/LocalStorageController.d.ts +47 -0
  119. package/dist/server-core/src/storage/LocalStorageController.d.ts.map +1 -0
  120. package/dist/server-core/src/storage/S3StorageController.d.ts +37 -0
  121. package/dist/server-core/src/storage/S3StorageController.d.ts.map +1 -0
  122. package/dist/server-core/src/storage/index.d.ts +26 -0
  123. package/dist/server-core/src/storage/index.d.ts.map +1 -0
  124. package/dist/server-core/src/storage/routes.d.ts +39 -0
  125. package/dist/server-core/src/storage/routes.d.ts.map +1 -0
  126. package/dist/server-core/src/storage/storage-registry.d.ts +79 -0
  127. package/dist/server-core/src/storage/storage-registry.d.ts.map +1 -0
  128. package/dist/server-core/src/storage/types.d.ts +104 -0
  129. package/dist/server-core/src/storage/types.d.ts.map +1 -0
  130. package/dist/server-core/src/types/index.d.ts +12 -0
  131. package/dist/server-core/src/types/index.d.ts.map +1 -0
  132. package/dist/server-core/src/utils/dev-port.d.ts +36 -0
  133. package/dist/server-core/src/utils/dev-port.d.ts.map +1 -0
  134. package/dist/server-core/src/utils/logger.d.ts +32 -0
  135. package/dist/server-core/src/utils/logger.d.ts.map +1 -0
  136. package/dist/server-core/src/utils/logging.d.ts +10 -0
  137. package/dist/server-core/src/utils/logging.d.ts.map +1 -0
  138. package/dist/server-core/src/utils/request-logger.d.ts +20 -0
  139. package/dist/server-core/src/utils/request-logger.d.ts.map +1 -0
  140. package/dist/server-core/src/utils/sql.d.ts +28 -0
  141. package/dist/server-core/src/utils/sql.d.ts.map +1 -0
  142. package/dist/server-mongodb/src/MongoBootstrapper.d.ts +18 -0
  143. package/dist/server-mongodb/src/MongoBootstrapper.d.ts.map +1 -0
  144. package/dist/server-mongodb/src/auth/ensure-collections.d.ts +3 -0
  145. package/dist/server-mongodb/src/auth/ensure-collections.d.ts.map +1 -0
  146. package/dist/server-mongodb/src/auth/services.d.ts +135 -0
  147. package/dist/server-mongodb/src/auth/services.d.ts.map +1 -0
  148. package/dist/server-mongodb/src/connection.d.ts +35 -0
  149. package/dist/server-mongodb/src/connection.d.ts.map +1 -0
  150. package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts +64 -0
  151. package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts.map +1 -0
  152. package/dist/server-mongodb/src/db/MongoEntityService.d.ts +98 -0
  153. package/dist/server-mongodb/src/db/MongoEntityService.d.ts.map +1 -0
  154. package/dist/server-mongodb/src/factory.d.ts +142 -0
  155. package/dist/server-mongodb/src/factory.d.ts.map +1 -0
  156. package/dist/server-mongodb/src/history/ensure-history-collection.d.ts +3 -0
  157. package/dist/server-mongodb/src/history/ensure-history-collection.d.ts.map +1 -0
  158. package/dist/server-mongodb/src/index.d.ts +18 -0
  159. package/dist/server-mongodb/src/index.d.ts.map +1 -0
  160. package/dist/server-mongodb/src/services/MongoDriver.d.ts +83 -0
  161. package/dist/server-mongodb/src/services/MongoDriver.d.ts.map +1 -0
  162. package/dist/server-mongodb/src/services/MongoHistoryService.d.ts +37 -0
  163. package/dist/server-mongodb/src/services/MongoHistoryService.d.ts.map +1 -0
  164. package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts +86 -0
  165. package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts.map +1 -0
  166. package/dist/server-mongodb/src/useMongoDriver.d.ts +18 -0
  167. package/dist/server-mongodb/src/useMongoDriver.d.ts.map +1 -0
  168. package/dist/server-mongodb/src/utils.d.ts +10 -0
  169. package/dist/server-mongodb/src/utils.d.ts.map +1 -0
  170. package/dist/server-mongodb/src/websocket.d.ts +7 -0
  171. package/dist/server-mongodb/src/websocket.d.ts.map +1 -0
  172. package/dist/types/src/controllers/analytics_controller.d.ts +8 -0
  173. package/dist/types/src/controllers/analytics_controller.d.ts.map +1 -0
  174. package/dist/types/src/controllers/auth.d.ts +120 -0
  175. package/dist/types/src/controllers/auth.d.ts.map +1 -0
  176. package/dist/types/src/controllers/client.d.ts +171 -0
  177. package/dist/types/src/controllers/client.d.ts.map +1 -0
  178. package/dist/types/src/controllers/collection_registry.d.ts +46 -0
  179. package/dist/types/src/controllers/collection_registry.d.ts.map +1 -0
  180. package/dist/types/src/controllers/customization_controller.d.ts +61 -0
  181. package/dist/types/src/controllers/customization_controller.d.ts.map +1 -0
  182. package/dist/types/src/controllers/data.d.ts +169 -0
  183. package/dist/types/src/controllers/data.d.ts.map +1 -0
  184. package/dist/types/src/controllers/data_driver.d.ts +161 -0
  185. package/dist/types/src/controllers/data_driver.d.ts.map +1 -0
  186. package/dist/types/src/controllers/database_admin.d.ts +12 -0
  187. package/dist/types/src/controllers/database_admin.d.ts.map +1 -0
  188. package/dist/types/src/controllers/dialogs_controller.d.ts +37 -0
  189. package/dist/types/src/controllers/dialogs_controller.d.ts.map +1 -0
  190. package/dist/types/src/controllers/effective_role.d.ts +5 -0
  191. package/dist/types/src/controllers/effective_role.d.ts.map +1 -0
  192. package/dist/types/src/controllers/email.d.ts +35 -0
  193. package/dist/types/src/controllers/email.d.ts.map +1 -0
  194. package/dist/types/src/controllers/index.d.ts +19 -0
  195. package/dist/types/src/controllers/index.d.ts.map +1 -0
  196. package/dist/types/src/controllers/local_config_persistence.d.ts +21 -0
  197. package/dist/types/src/controllers/local_config_persistence.d.ts.map +1 -0
  198. package/dist/types/src/controllers/navigation.d.ts +214 -0
  199. package/dist/types/src/controllers/navigation.d.ts.map +1 -0
  200. package/dist/types/src/controllers/registry.d.ts +55 -0
  201. package/dist/types/src/controllers/registry.d.ts.map +1 -0
  202. package/dist/types/src/controllers/side_dialogs_controller.d.ts +68 -0
  203. package/dist/types/src/controllers/side_dialogs_controller.d.ts.map +1 -0
  204. package/dist/types/src/controllers/side_entity_controller.d.ts +91 -0
  205. package/dist/types/src/controllers/side_entity_controller.d.ts.map +1 -0
  206. package/dist/types/src/controllers/snackbar.d.ts +25 -0
  207. package/dist/types/src/controllers/snackbar.d.ts.map +1 -0
  208. package/dist/types/src/controllers/storage.d.ts +172 -0
  209. package/dist/types/src/controllers/storage.d.ts.map +1 -0
  210. package/dist/types/src/index.d.ts +5 -0
  211. package/dist/types/src/index.d.ts.map +1 -0
  212. package/dist/types/src/rebase_context.d.ts +106 -0
  213. package/dist/types/src/rebase_context.d.ts.map +1 -0
  214. package/dist/types/src/types/backend.d.ts +537 -0
  215. package/dist/types/src/types/backend.d.ts.map +1 -0
  216. package/dist/types/src/types/builders.d.ts +16 -0
  217. package/dist/types/src/types/builders.d.ts.map +1 -0
  218. package/dist/types/src/types/chips.d.ts +6 -0
  219. package/dist/types/src/types/chips.d.ts.map +1 -0
  220. package/dist/types/src/types/collections.d.ts +857 -0
  221. package/dist/types/src/types/collections.d.ts.map +1 -0
  222. package/dist/types/src/types/cron.d.ts +103 -0
  223. package/dist/types/src/types/cron.d.ts.map +1 -0
  224. package/dist/types/src/types/data_source.d.ts +65 -0
  225. package/dist/types/src/types/data_source.d.ts.map +1 -0
  226. package/dist/types/src/types/entities.d.ts +146 -0
  227. package/dist/types/src/types/entities.d.ts.map +1 -0
  228. package/dist/types/src/types/entity_actions.d.ts +99 -0
  229. package/dist/types/src/types/entity_actions.d.ts.map +1 -0
  230. package/dist/types/src/types/entity_callbacks.d.ts +174 -0
  231. package/dist/types/src/types/entity_callbacks.d.ts.map +1 -0
  232. package/dist/types/src/types/entity_link_builder.d.ts +8 -0
  233. package/dist/types/src/types/entity_link_builder.d.ts.map +1 -0
  234. package/dist/types/src/types/entity_overrides.d.ts +11 -0
  235. package/dist/types/src/types/entity_overrides.d.ts.map +1 -0
  236. package/dist/types/src/types/entity_views.d.ts +62 -0
  237. package/dist/types/src/types/entity_views.d.ts.map +1 -0
  238. package/dist/types/src/types/export_import.d.ts +22 -0
  239. package/dist/types/src/types/export_import.d.ts.map +1 -0
  240. package/dist/types/src/types/index.d.ts +24 -0
  241. package/dist/types/src/types/index.d.ts.map +1 -0
  242. package/dist/types/src/types/locales.d.ts +5 -0
  243. package/dist/types/src/types/locales.d.ts.map +1 -0
  244. package/dist/types/src/types/modify_collections.d.ts +6 -0
  245. package/dist/types/src/types/modify_collections.d.ts.map +1 -0
  246. package/dist/types/src/types/plugins.d.ts +280 -0
  247. package/dist/types/src/types/plugins.d.ts.map +1 -0
  248. package/dist/types/src/types/properties.d.ts +1177 -0
  249. package/dist/types/src/types/properties.d.ts.map +1 -0
  250. package/dist/types/src/types/property_config.d.ts +71 -0
  251. package/dist/types/src/types/property_config.d.ts.map +1 -0
  252. package/dist/types/src/types/relations.d.ts +337 -0
  253. package/dist/types/src/types/relations.d.ts.map +1 -0
  254. package/dist/types/src/types/slots.d.ts +253 -0
  255. package/dist/types/src/types/slots.d.ts.map +1 -0
  256. package/dist/types/src/types/translations.d.ts +871 -0
  257. package/dist/types/src/types/translations.d.ts.map +1 -0
  258. package/dist/types/src/types/user_management_delegate.d.ts +122 -0
  259. package/dist/types/src/types/user_management_delegate.d.ts.map +1 -0
  260. package/dist/types/src/types/websockets.d.ts +79 -0
  261. package/dist/types/src/types/websockets.d.ts.map +1 -0
  262. package/dist/types/src/users/index.d.ts +3 -0
  263. package/dist/types/src/users/index.d.ts.map +1 -0
  264. package/dist/types/src/users/roles.d.ts +23 -0
  265. package/dist/types/src/users/roles.d.ts.map +1 -0
  266. package/dist/types/src/users/user.d.ts +47 -0
  267. package/dist/types/src/users/user.d.ts.map +1 -0
  268. package/dist/websocket-BZlPuJrt.js +220 -0
  269. package/dist/websocket-BZlPuJrt.js.map +1 -0
  270. package/package.json +79 -0
  271. package/src/MongoBootstrapper.ts +177 -0
  272. package/src/auth/ensure-collections.ts +94 -0
  273. package/src/auth/services.ts +638 -0
  274. package/src/connection.ts +60 -0
  275. package/src/db/MongoConditionBuilder.ts +181 -0
  276. package/src/db/MongoEntityService.ts +350 -0
  277. package/src/factory.ts +289 -0
  278. package/src/history/ensure-history-collection.ts +19 -0
  279. package/src/index.ts +25 -0
  280. package/src/services/MongoDriver.ts +297 -0
  281. package/src/services/MongoDriver.ts.backup +266 -0
  282. package/src/services/MongoHistoryService.ts +154 -0
  283. package/src/services/MongoRealtimeService.ts +394 -0
  284. package/src/useMongoDriver.ts +519 -0
  285. package/src/utils.ts +28 -0
  286. 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
+ }