@flowerforce/flowerbase 1.0.1-beta.8 → 1.0.2

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 (178) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +1 -1
  3. package/README.md +466 -7
  4. package/dist/auth/controller.d.ts.map +1 -1
  5. package/dist/auth/controller.js +11 -1
  6. package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
  7. package/dist/auth/providers/local-userpass/controller.js +15 -15
  8. package/dist/auth/utils.d.ts +2 -1
  9. package/dist/auth/utils.d.ts.map +1 -1
  10. package/dist/auth/utils.js +14 -10
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +3 -3
  13. package/dist/features/endpoints/utils.d.ts +1 -1
  14. package/dist/features/endpoints/utils.d.ts.map +1 -1
  15. package/dist/features/endpoints/utils.js +5 -2
  16. package/dist/features/functions/controller.d.ts.map +1 -1
  17. package/dist/features/functions/controller.js +12 -8
  18. package/dist/features/functions/dtos.d.ts +2 -1
  19. package/dist/features/functions/dtos.d.ts.map +1 -1
  20. package/dist/features/functions/interface.d.ts +2 -1
  21. package/dist/features/functions/interface.d.ts.map +1 -1
  22. package/dist/features/functions/utils.d.ts +1 -1
  23. package/dist/features/functions/utils.d.ts.map +1 -1
  24. package/dist/features/functions/utils.js +4 -4
  25. package/dist/features/triggers/index.d.ts.map +1 -1
  26. package/dist/features/triggers/index.js +9 -3
  27. package/dist/features/triggers/interface.d.ts +4 -4
  28. package/dist/features/triggers/interface.d.ts.map +1 -1
  29. package/dist/features/triggers/utils.d.ts.map +1 -1
  30. package/dist/features/triggers/utils.js +25 -14
  31. package/dist/global.d.ts +9 -0
  32. package/dist/global.d.ts.map +1 -0
  33. package/dist/global.js +2 -0
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +13 -9
  37. package/dist/model.d.ts +1 -0
  38. package/dist/model.d.ts.map +1 -1
  39. package/dist/model.js +15 -0
  40. package/dist/services/api/index.d.ts.map +1 -1
  41. package/dist/services/api/index.js +6 -1
  42. package/dist/services/aws/index.d.ts.map +1 -1
  43. package/dist/services/aws/index.js +5 -5
  44. package/dist/services/index.d.ts.map +1 -1
  45. package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
  46. package/dist/services/mongodb-atlas/index.js +76 -71
  47. package/dist/services/mongodb-atlas/model.d.ts +3 -3
  48. package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
  49. package/dist/services/mongodb-atlas/utils.d.ts.map +1 -1
  50. package/dist/state.d.ts +2 -2
  51. package/dist/state.d.ts.map +1 -1
  52. package/dist/utils/context/helpers.d.ts +4 -4
  53. package/dist/utils/context/helpers.d.ts.map +1 -1
  54. package/dist/utils/context/helpers.js +1 -1
  55. package/dist/utils/context/index.d.ts.map +1 -1
  56. package/dist/utils/context/index.js +6 -5
  57. package/dist/utils/helpers/someAsync.d.ts.map +1 -1
  58. package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -1
  59. package/dist/utils/initializer/exposeRoutes.js +44 -1
  60. package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
  61. package/dist/utils/initializer/registerPlugins.js +9 -9
  62. package/dist/utils/roles/helpers.d.ts.map +1 -1
  63. package/dist/utils/roles/helpers.js +9 -7
  64. package/dist/utils/roles/interface.d.ts.map +1 -1
  65. package/dist/utils/roles/machines/commonValidators.d.ts +2 -2
  66. package/dist/utils/roles/machines/commonValidators.d.ts.map +1 -1
  67. package/dist/utils/roles/machines/commonValidators.js +5 -6
  68. package/dist/utils/roles/machines/index.d.ts.map +1 -1
  69. package/dist/utils/roles/machines/interface.d.ts.map +1 -1
  70. package/dist/utils/roles/machines/machine.d.ts +3 -3
  71. package/dist/utils/roles/machines/machine.d.ts.map +1 -1
  72. package/dist/utils/roles/machines/machine.js +12 -4
  73. package/dist/utils/roles/machines/read/A/index.d.ts.map +1 -1
  74. package/dist/utils/roles/machines/read/A/index.js +12 -2
  75. package/dist/utils/roles/machines/read/B/index.d.ts.map +1 -1
  76. package/dist/utils/roles/machines/read/B/index.js +20 -5
  77. package/dist/utils/roles/machines/read/C/index.d.ts.map +1 -1
  78. package/dist/utils/roles/machines/read/C/index.js +20 -5
  79. package/dist/utils/roles/machines/read/D/index.d.ts.map +1 -1
  80. package/dist/utils/roles/machines/read/D/index.js +13 -3
  81. package/dist/utils/roles/machines/read/D/validators.d.ts +1 -1
  82. package/dist/utils/roles/machines/read/D/validators.d.ts.map +1 -1
  83. package/dist/utils/roles/machines/read/D/validators.js +8 -4
  84. package/dist/utils/roles/machines/utils.d.ts +4 -4
  85. package/dist/utils/roles/machines/utils.d.ts.map +1 -1
  86. package/dist/utils/roles/machines/utils.js +5 -1
  87. package/dist/utils/roles/machines/write/A/index.d.ts.map +1 -1
  88. package/dist/utils/roles/machines/write/A/index.js +13 -3
  89. package/dist/utils/roles/machines/write/B/index.d.ts.map +1 -1
  90. package/dist/utils/roles/machines/write/B/index.js +37 -10
  91. package/dist/utils/roles/machines/write/C/index.d.ts.map +1 -1
  92. package/dist/utils/roles/machines/write/C/index.js +13 -3
  93. package/dist/utils/roles/machines/write/C/validators.d.ts +1 -1
  94. package/dist/utils/roles/machines/write/C/validators.d.ts.map +1 -1
  95. package/dist/utils/roles/machines/write/C/validators.js +8 -4
  96. package/dist/utils/rules-matcher/interface.d.ts.map +1 -1
  97. package/dist/utils/rules-matcher/utils.d.ts.map +1 -1
  98. package/dist/utils/rules.d.ts.map +1 -1
  99. package/package.json +9 -2
  100. package/src/auth/controller.ts +12 -1
  101. package/src/auth/providers/local-userpass/controller.ts +47 -39
  102. package/src/auth/providers/local-userpass/dtos.ts +1 -1
  103. package/src/auth/utils.ts +24 -18
  104. package/src/constants.ts +7 -3
  105. package/src/features/endpoints/utils.ts +6 -4
  106. package/src/features/functions/controller.ts +23 -22
  107. package/src/features/functions/dtos.ts +9 -9
  108. package/src/features/functions/interface.ts +2 -1
  109. package/src/features/functions/utils.ts +12 -12
  110. package/src/features/triggers/index.ts +9 -6
  111. package/src/features/triggers/interface.ts +9 -10
  112. package/src/features/triggers/utils.ts +57 -29
  113. package/src/global.ts +9 -0
  114. package/src/index.ts +16 -11
  115. package/src/model.ts +3 -1
  116. package/src/services/api/index.ts +6 -1
  117. package/src/services/aws/index.ts +19 -17
  118. package/src/services/mongodb-atlas/index.ts +204 -163
  119. package/src/services/mongodb-atlas/model.ts +13 -13
  120. package/src/services/mongodb-atlas/utils.ts +6 -4
  121. package/src/state.ts +32 -20
  122. package/src/utils/__tests__/STEP_A_STATES.test.ts +78 -47
  123. package/src/utils/__tests__/STEP_B_STATES.test.ts +168 -105
  124. package/src/utils/__tests__/STEP_C_STATES.test.ts +150 -78
  125. package/src/utils/__tests__/STEP_D_STATES.test.ts +129 -86
  126. package/src/utils/__tests__/checkAdditionalFieldsFn.test.ts +35 -35
  127. package/src/utils/__tests__/checkApplyWhen.test.ts +40 -41
  128. package/src/utils/__tests__/checkFieldsPropertyExists.test.ts +40 -40
  129. package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +185 -184
  130. package/src/utils/__tests__/comparePassword.test.ts +27 -30
  131. package/src/utils/__tests__/evaluateDocumentsFiltersReadFn.test.ts +55 -47
  132. package/src/utils/__tests__/evaluateDocumentsFiltersWriteFn.test.ts +61 -47
  133. package/src/utils/__tests__/evaluateTopLevelReadFn.test.ts +48 -48
  134. package/src/utils/__tests__/evaluateTopLevelWriteFn.test.ts +56 -56
  135. package/src/utils/__tests__/exposeRoutes.test.ts +46 -44
  136. package/src/utils/__tests__/generateContextData.test.ts +57 -51
  137. package/src/utils/__tests__/getDefaultRule.test.ts +32 -27
  138. package/src/utils/__tests__/getKey.test.ts +10 -10
  139. package/src/utils/__tests__/getKeys.test.ts +10 -9
  140. package/src/utils/__tests__/getWinningRole.test.ts +57 -50
  141. package/src/utils/__tests__/hashPassword.test.ts +24 -25
  142. package/src/utils/__tests__/isEmpty.test.ts +14 -15
  143. package/src/utils/__tests__/logMachineInfo.test.ts +12 -12
  144. package/src/utils/__tests__/operators.test.ts +94 -96
  145. package/src/utils/__tests__/readFileContent.test.ts +28 -28
  146. package/src/utils/__tests__/registerPlugins.test.ts +44 -32
  147. package/src/utils/__tests__/rule.test.ts +47 -49
  148. package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +57 -52
  149. package/src/utils/__tests__/rulesMatcherUtils.test.ts +64 -53
  150. package/src/utils/__tests__/someAsync.test.ts +46 -49
  151. package/src/utils/context/helpers.ts +1 -1
  152. package/src/utils/context/index.ts +9 -10
  153. package/src/utils/crypto/index.ts +2 -2
  154. package/src/utils/helpers/someAsync.ts +11 -11
  155. package/src/utils/initializer/exposeRoutes.ts +56 -2
  156. package/src/utils/initializer/registerPlugins.ts +11 -13
  157. package/src/utils/roles/helpers.ts +22 -15
  158. package/src/utils/roles/interface.ts +2 -3
  159. package/src/utils/roles/machines/commonValidators.ts +23 -14
  160. package/src/utils/roles/machines/index.ts +7 -4
  161. package/src/utils/roles/machines/interface.ts +17 -5
  162. package/src/utils/roles/machines/machine.ts +97 -72
  163. package/src/utils/roles/machines/read/A/index.ts +12 -4
  164. package/src/utils/roles/machines/read/B/index.ts +20 -7
  165. package/src/utils/roles/machines/read/C/index.ts +24 -8
  166. package/src/utils/roles/machines/read/D/index.ts +14 -8
  167. package/src/utils/roles/machines/read/D/validators.ts +21 -13
  168. package/src/utils/roles/machines/read/index.ts +5 -5
  169. package/src/utils/roles/machines/utils.ts +30 -13
  170. package/src/utils/roles/machines/write/A/index.ts +13 -5
  171. package/src/utils/roles/machines/write/B/index.ts +42 -16
  172. package/src/utils/roles/machines/write/C/index.ts +14 -8
  173. package/src/utils/roles/machines/write/C/validators.ts +21 -13
  174. package/src/utils/roles/machines/write/index.ts +4 -4
  175. package/src/utils/rules-matcher/interface.ts +4 -4
  176. package/src/utils/rules-matcher/utils.ts +10 -6
  177. package/src/utils/rules.ts +12 -5
  178. package/src/global.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -0,0 +1,17 @@
1
+ ## 1.0.2 (2025-06-30)
2
+
3
+
4
+ ### 🩹 Fixes
5
+
6
+ - license ([8f5f2e2](https://github.com/flowerforce/flowerbase/commit/8f5f2e2))
7
+
8
+ - update package license ([9b05f27](https://github.com/flowerforce/flowerbase/commit/9b05f27))
9
+
10
+ - package lock ([b63c9c1](https://github.com/flowerforce/flowerbase/commit/b63c9c1))
11
+
12
+ ## 1.0.1 (2025-06-30)
13
+
14
+
15
+ ### 🩹 Fixes
16
+
17
+ - readme format ([0cd2b8a](https://github.com/flowerforce/flowerbase/commit/0cd2b8a))
package/LICENSE CHANGED
@@ -1,3 +1,3 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 FlowerForce
3
+ Copyright (c) 2025 Flowerbase
package/README.md CHANGED
@@ -1,18 +1,477 @@
1
1
  # flowerbase
2
2
 
3
- > **A serverless-native MongoDB package designed for modern cloud applications. Lightweight. Fast. Pay-as-you-go.**
3
+ > **A serverless-native MongoDB package designed for modern cloud applications**
4
+
5
+ Unlike MongoDB Realm or other cloud platforms, we do not offer a graphical interface where you can configure services through a dashboard.
6
+ Instead, everything is code-based and developer-driven, offering full flexibility through configuration files and source code.
7
+
8
+ This documentation is structured to guide both experienced Realm users and newcomers alike — whether you’re migrating or starting clean.
9
+
10
+ #### 🧠 Features Summary
11
+ | Feature | Status |
12
+ |--------------------------|-----------------------------------------|
13
+ | Realm-compatible schema | ✅ Supported (unchanged) |
14
+ | Authentication strategy | ✅ Local Email/Password only |
15
+ | OAuth / API Keys / etc. | 🚫 Not supported (for now) |
16
+ | User data accessibility | ✅ Stored in your main DB |
17
+ | Device Sync | 🚫 Not supported (for now) |
18
+ | Functions | ✅ Supported (unchanged) |
19
+ | Triggers | ✅ Supported (unchanged) |
20
+ | HTTP Endpoints | ✅ Supported (unchanged) |
21
+
22
+
23
+ > ⚠️ **Already have an existing Realm project?**
24
+ > You can skip ahead to the [Migration Guide](#migration) to quickly adapt your project to Flowerbase.
25
+
26
+
27
+ ## 🚀 Creating a New Project from Scratch
28
+
29
+ If you're starting fresh, you’ll learn how to:
30
+
31
+ - Scaffold a minimal Node.js + TypeScript backend
32
+ - Install and configure `@flowerforce/flowerbase`
33
+ - Set up authentication, data models, rules, and custom logic
34
+ - Deploy your app and connect it to any frontend (React, Vue, mobile, etc.)
35
+
36
+ ## 📁 1. Project Setup
37
+
38
+ ### ✅ Step 1.1 – Initialize a Node.js Application
39
+
40
+ Create a new project directory and initialize it with npm:
41
+
42
+ ```bash
43
+ mkdir my-app
44
+ cd my-app
45
+ npm init -y
46
+ ```
47
+
48
+ ### ✅ Step 1.2 – Install Dependencies
49
+ Install the `@flowerforce/flowerbase` library, which provides the tools required for managing your data with MongoDB Atlas:
50
+
51
+ ```bash
52
+ npm install @flowerforce/flowerbase
53
+ ```
54
+
55
+ Add Typescript
56
+
57
+ ```bash
58
+ npm install --save-dev typescript @types/node ts-node
59
+ ```
60
+
61
+ Add `tsconfig.json` file
62
+
63
+ ```bash
64
+ npx tsc --init
65
+ ```
66
+
67
+ In your `packages.json`, inside the script section add this:
68
+
69
+ ```json
70
+ {
71
+ "start": "ts-node index.ts"
72
+ }
73
+ ```
74
+
75
+ ## 🏗️ 2. Create the Project Structure
76
+ Inside your project root, create the main source directory:
77
+
78
+ ```bash
79
+ mkdir src
80
+ ```
81
+ Within the src folder, add a new file named index.ts:
82
+
83
+ ```bash
84
+ touch src/index.ts
85
+ ```
86
+
87
+ ## 🌿 3. Environment Variables
88
+ Ensure the following environment variables are set in your .env file or deployment environment:
89
+
90
+
91
+ | Variable | Description | Example |
92
+ | ---------------------- | --------------------------------------------------------------------------- | -------------------------------------------------- |
93
+ | `PROJECT_ID` | A unique ID to identify your project. This value can be freely invented — it's preserved mainly for compatibility with the old Realm-style project structure. | `my-flowerbase-app` |
94
+ | `PORT` | The port on which the server will run. | `3000` |
95
+ | `DB_CONNECTION_STRING` | MongoDB connection URI, including username, password, and database name. | `mongodb+srv://user:pass@cluster.mongodb.net/mydb` |
96
+ | `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
97
+ | `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
98
+ | `HTTPS_SCHEMA` | The schema for your server requests (usually `https` or `http`). | `http` |
99
+
100
+
101
+ Example:
102
+ ```env
103
+ PROJECT_ID=your-project-id
104
+ PORT=3000
105
+ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
106
+ APP_SECRET=your-jwt-secret
107
+ HOST=0.0.0.0
108
+ HTTPS_SCHEMA=http
109
+ ```
110
+
111
+ 🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
112
+
113
+
114
+ ## 🧩 4. Initialize Flowerbase
115
+ In your index.ts file, import the initialize function from the `@flowerforce/flowerbase` package and invoke it:
116
+
117
+ ```ts
118
+ // src/index.ts
119
+ import { initialize } from '@flowerforce/flowerbase';
120
+
121
+ const projectId = process.env.PROJECT_ID ?? "my-project-id"
122
+ const port = process.env.PORT ? Number(process.env.PORT) : undefined
123
+ const mongodbUrl = process.env.DB_CONNECTION_STRING
124
+ const jwtSecret = process.env.APP_SECRET
125
+ const host = process.env.HOST
126
+
127
+ initialize({
128
+ projectId,
129
+ port,
130
+ mongodbUrl,
131
+ jwtSecret,
132
+ host
133
+ })
134
+ ```
135
+
136
+ This initializes the Flowerbase integration, connecting your application to MongoDB Atlas.
137
+
138
+ ## 🛠️ 5. Server Configuration – Authentication, Rules, and Functions
139
+ After setting up the base Flowerbase integration, you can now configure advanced features to control how your backend behaves.
140
+
141
+ ### 📁 Suggested Folder Structure
142
+
143
+ ```code
144
+ 📁 my-app/
145
+ |
146
+ ├── 📁 src/
147
+ | |
148
+ │ ├── 📄 index.ts
149
+ | |
150
+ │ ├── 📁 auth/
151
+ | | |
152
+ │ │ └── 📄 custom_user_data.json
153
+ | | |
154
+ │ │ └── 📄 providers.json
155
+ | |
156
+ │ ├── 📁 data_sources/
157
+ | | |
158
+ │ │ └── 📁 mongodb-atlas/
159
+ | | |
160
+ │ │ └── 📁 your_db_name/
161
+ | | |
162
+ │ │ └── 📁 collection1/
163
+ | | | |
164
+ │ │ | └── 📄 rules.json
165
+ │ │ |
166
+ │ │ └── 📁 collection2/
167
+ | | |
168
+ │ │ └── 📄 rules.json
169
+ │ │
170
+ │ ├── 📁 functions/
171
+ │ │ |
172
+ │ │ └── 📄 exampleFunction.ts
173
+ │ │ |
174
+ │ │ └── 📄 config.json
175
+ │ │
176
+ │ ├── 📁 triggers/
177
+ │ │ |
178
+ │ │ └── 📄 trigger1.json
179
+ │ │ |
180
+ │ │ └── 📄 trigger2.json
181
+ │ │
182
+ │ ├── 📁 http_endpoints/
183
+ │ │ |
184
+ │ │ └── 📄 config.json
185
+ │ │
186
+ └── 📄 .env
187
+ ```
188
+
189
+ #### 📖 Structure summary
190
+ | Area | Description | Link |
191
+ | ---------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
192
+ | 🧠 Functions | Overview of server-side functions in Realm | [Functions Documentation](https://www.mongodb.com/docs/atlas/app-services/functions/) |
193
+ | ⏰ Triggers | Triggers that run on database events or schedules | [Triggers Documentation](https://www.mongodb.com/docs/atlas/app-services/triggers/) |
194
+ | 👤 User Management | Managing users, authentication, and providers | [Users Documentation](https://www.mongodb.com/docs/atlas/app-services/users/) |
195
+ | 🌐 Custom Endpoints | HTTP endpoints to expose backend functionality via API | [Custom Endpoints](http://mongodb.com/docs/atlas/app-services/data-api/custom-endpoints/) |
196
+ | 🔐 Rules & Permissions | Define fine-grained access control for collections | [Rules Documentation](https://www.mongodb.com/docs/atlas/app-services/rules/) |
197
+
198
+
199
+ ## 🔐 6. Authentication – Local Email/Password (User-Pass)
200
+
201
+ The authentication system in `@flowerforce/flowerbase` reimplements the classic **email/password** login method (called local-userpass), similar to the one used by MongoDB Realm.
202
+
203
+ ### 🧱 Compatibility with Realm
204
+
205
+ In MongoDB Atlas (Realm), users were stored in a separate internal authentication database, not directly accessible via the standard MongoDB collections.
206
+
207
+ However, with Flowerbase:
208
+
209
+ - Users are stored directly in a MongoDB collection (by default named auth_users), but this can be customized in the server project via a JSON configuration file, as shown later in this guide.
210
+
211
+ - The document structure remains identical to the previous Realm implementation
212
+
213
+ - No changes are required to migrate the user data — existing user documents will continue to work as-is.
214
+ However, all users will be required to reset their passwords since it is not possible to extract passwords from the old MongoDB authentication system.
215
+
216
+ ### ✅ Supported Auth Method
217
+
218
+ The only authentication mode currently re-implemented in `@flowerforce/flowerbase` is:
219
+
220
+ - Local Email/Password (local-userpass)
221
+
222
+ > Other methods (OAuth, API key, anonymous, etc.) are not supported yet.
223
+
224
+ #### Example user:
225
+ ```js
226
+ {
227
+ "_id": ObjectId("2scgsb3gev99gsty2ev3g2g323d2hs"),
228
+ "email": "myuser@flowerbase.example",
229
+ "password": "your-encrypted-password",
230
+ "status": "confirmed",
231
+ "identities": [
232
+ {
233
+ "id": "example-id",
234
+ "provider_type": "local-userpass",
235
+ "provider_id": "example-provider-id",
236
+ "provider_data": {
237
+ "email": "myuser@flowerbase.example",
238
+ }
239
+ }
240
+ ]
241
+ }
242
+ ```
243
+
244
+ You can specify the MongoDB collection used to store authentication users by configuring the `auth_collection` field inside the `auth/providers.json` file.
245
+
246
+ #### 📁 auth/providers.json
247
+ Example
248
+ ```json
249
+ {
250
+ "api-key": {
251
+ "name": "api-key",
252
+ "type": "api-key",
253
+ "disabled": true
254
+ },
255
+ "local-userpass": {
256
+ "name": "local-userpass",
257
+ "type": "local-userpass",
258
+ "disabled": false,
259
+ "auth_collection": "my-users-collection" //custom collection name
260
+ "config": {
261
+ "autoConfirm": true,
262
+ "resetPasswordSubject": "reset",
263
+ "resetPasswordUrl": "https://my.app.url/password-reset",
264
+ "runConfirmationFunction": false
265
+ }
266
+ }
267
+ }
268
+
269
+ ```
270
+ If you're configuring the project from scratch, you can skip ahead to the [Build](#build) step.
271
+
272
+ --------
273
+
274
+
275
+ <a id="migration"></a>
276
+ ## 🔄 [Migration Guide](#migration) - Migrating Your Realm Project
277
+
278
+ Follow these steps to rebuild your backend in a clean and modern Node.js environment:
279
+
280
+ ## 🪜 Step-by-Step Migration
281
+
282
+ ### 📥 Download Your Realm App from MongoDB Atlas
283
+
284
+ Follow these steps to export and download your Realm app from MongoDB Cloud.
4
285
 
5
286
  ---
6
287
 
7
- ## Features
288
+ #### 1. Log In to MongoDB Cloud
8
289
 
9
- - 🚀 **Serverless-ready** built from the ground up to work in serverless environments like AWS Lambda.
10
- - 🔄 **MongoDB-compatible API** — drop-in replacement for most common MongoDB queries and models.
11
- - 🔐 **Secure by default** — Strict access rules.
290
+ Go to [https://cloud.mongodb.com/](https://cloud.mongodb.com/) and sign in with your credentials.
12
291
 
13
292
  ---
14
293
 
15
- ## 📦 Installation
294
+ #### 2. Select Your Project
295
+
296
+ From the dashboard, choose the **project** that contains the Realm app you want to download.
297
+
298
+ ---
299
+
300
+ #### 3. Open the Realm App List
301
+
302
+ - In the left-hand sidebar, under the **Services** section, click on **"Triggers"**.
303
+ - Then click the **"View All Apps"** button in the top-right corner.
304
+
305
+ ---
306
+
307
+ #### 4. Select the Desired App
308
+
309
+ From the list of applications, click on the **app name** you wish to export.
310
+
311
+ ---
312
+
313
+ #### 5. Go to Deployment
314
+
315
+ In the left sidebar, under the **Manage** section, click on **"Deployment"**.
316
+
317
+ ---
318
+
319
+ #### 6. Export the App
320
+
321
+ Click on the **"Export App"** tab at the top of the page.
322
+
323
+ ---
324
+
325
+ #### 7. Download the App
326
+
327
+ Scroll to the bottom and click the **"Download App"** button.
328
+
329
+ This will download a `.zip` file containing your Realm app's full structure and configuration.
330
+
331
+ ---
332
+
333
+ ✅ You are now ready to migrate or inspect your Realm app locally!
334
+
335
+ 1) In your existing project folder, initialize a new Node.js project, Run:
336
+
337
+ ```bash
338
+ npm init -y
339
+ ```
340
+ 2) Install Flowerbase
341
+
342
+ ```bash
343
+ npm install @flowerforce/flowerbase
344
+ ```
345
+
346
+ 3) Add Typescript
347
+
348
+ ```bash
349
+ npm install --save-dev typescript @types/node ts-node
350
+ ```
351
+
352
+
353
+ 4) Add `tsconfig.json` file
354
+
355
+ ```bash
356
+ npx tsc --init
357
+ ```
358
+
359
+ 5) Create an index.ts file
360
+
361
+ Inside your project, create index.ts:
362
+
363
+ ```bash
364
+ touch index.ts
365
+ ```
366
+
367
+ 6) In your `packages.json`, inside the script section add this:
368
+
369
+ ```json
370
+ {
371
+ "start": "ts-node index.ts"
372
+ }
373
+ ```
374
+
375
+ Initialize the Flowerbase App
376
+
377
+ In index.ts, add:
378
+
379
+ ```ts
380
+ import { initialize } from '@flowerforce/flowerbase';
381
+
382
+ const projectId = process.env.PROJECT_ID ?? "my-project-id"
383
+ const port = process.env.PORT ? Number(process.env.PORT) : undefined
384
+ const mongodbUrl = process.env.DB_CONNECTION_STRING
385
+ const jwtSecret = process.env.APP_SECRET
386
+ const host = process.env.HOST
387
+
388
+ initialize({
389
+ projectId,
390
+ port,
391
+ mongodbUrl,
392
+ jwtSecret,
393
+ host
394
+ })
395
+
396
+ ```
397
+
398
+ Ensure the following environment variables are set in your .env file or deployment environment:
399
+
400
+
401
+ | Variable | Description | Example |
402
+ | ---------------------- | --------------------------------------------------------------------------- | -------------------------------------------------- |
403
+ | `PROJECT_ID` | A unique ID to identify your project. This value can be freely invented — it's preserved mainly for compatibility with the old Realm-style project structure. | `my-flowerbase-app` |
404
+ | `PORT` | The port on which the server will run. | `3000` |
405
+ | `DB_CONNECTION_STRING` | MongoDB connection URI, including username, password, and database name. | `mongodb+srv://user:pass@cluster.mongodb.net/mydb` |
406
+ | `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
407
+ | `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
408
+ | `HTTPS_SCHEMA` | The schema for your server requests (usually `https` or `http`). | `http` |
409
+
410
+
411
+ Example:
412
+ ```env
413
+ PROJECT_ID=your-project-id
414
+ PORT=3000
415
+ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
416
+ APP_SECRET=your-jwt-secret
417
+ HOST=0.0.0.0
418
+ HTTPS_SCHEMA=http
419
+ ```
420
+
421
+ 🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
422
+
423
+
424
+ <a id="build"></a>
425
+ ## 🚀 Build & Deploy the Server
426
+
427
+ Once your migration or first configuration is complete, it’s time to build and deploy the backend so it can be accessed by your frontend or external clients.
428
+
429
+ ### 🔧 Build the App
430
+
431
+ If you're using for example TypeScript:
16
432
 
17
433
  ```bash
18
- npm install flowerbase
434
+ npx tsc
435
+ ```
436
+
437
+
438
+ You can deploy the application using any Node.js-compatible platform.
439
+ Once deployed, you'll receive a public URL (e.g. https://your-app-name.up.example.app).
440
+
441
+ >This URL should be used as the base URL in your frontend application, as explained in the next section.
442
+
443
+ ## 🌐 Frontend Setup – Realm SDK in React (Example)
444
+
445
+ You can use the official `realm-web` SDK to integrate MongoDB Realm into a React application.
446
+ This serves as a sample setup — similar logic can be applied using other official Realm SDKs **(e.g. React Native, Node, or Flutter)**.
447
+
448
+ ### 📦 Install Realm SDK
449
+
450
+ ```bash
451
+ npm install realm-web
452
+ ```
453
+
454
+ ### ⚙️ Configure Realm in React
455
+
456
+ Create a file to initialize and export the Realm App instance:
457
+
458
+ ```ts
459
+ // src/realm/realmApp.ts
460
+
461
+ import * as Realm from "realm-web";
462
+
463
+ // Replace with your actual Realm App ID and your deployed backend URL
464
+ const app = new Realm.App({
465
+ id: "your-realm-app-id", // e.g., my-app-abcde
466
+ baseUrl: "https://your-deployed-backend-url.com" // e.g., https://your-app-name.up.example.app
467
+ });
468
+
469
+ export default app;
470
+
471
+ ```
472
+
473
+ >🔗 The baseUrl should point to the backend URL you deployed earlier using Flowerbase.
474
+ This tells the frontend SDK where to send authentication and data requests.
475
+
476
+
477
+
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAOzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBAgExD"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAOzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBA2ExD"}
@@ -65,12 +65,22 @@ function authController(app) {
65
65
  if (!auth_user) {
66
66
  throw new Error(`User with ID ${req.user.sub} not found`);
67
67
  }
68
- const user = yield db.collection(userCollection).findOne({ [constants_1.AUTH_CONFIG.user_id_field]: req.user.sub });
68
+ const user = yield db
69
+ .collection(userCollection)
70
+ .findOne({ [constants_1.AUTH_CONFIG.user_id_field]: req.user.sub });
69
71
  res.status(201);
70
72
  return {
71
73
  access_token: this.createAccessToken(Object.assign(Object.assign({}, auth_user), { user_data: user }))
72
74
  };
73
75
  });
74
76
  });
77
+ /**
78
+ * Endpoint to destroy the existing session.
79
+ */
80
+ app.delete(utils_1.AUTH_ENDPOINTS.SESSION, function () {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ return { status: "ok" };
83
+ });
84
+ });
75
85
  });
76
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAiBzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBA0MjE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAsBzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBA6MjE"}
@@ -108,12 +108,12 @@ function localUserPassController(app) {
108
108
  });
109
109
  });
110
110
  /**
111
- * Endpoint for reset password.
112
- *
113
- * @route {POST} /reset/call
114
- * @param {ResetPasswordDto} req - The request object with th reset request.
115
- * @returns {Promise<void>}
116
- */
111
+ * Endpoint for reset password.
112
+ *
113
+ * @route {POST} /reset/call
114
+ * @param {ResetPasswordDto} req - The request object with th reset request.
115
+ * @returns {Promise<void>}
116
+ */
117
117
  app.post(utils_1.AUTH_ENDPOINTS.RESET, {
118
118
  schema: utils_1.RESET_SCHEMA
119
119
  }, function (req) {
@@ -130,8 +130,8 @@ function localUserPassController(app) {
130
130
  const tokenId = (0, crypto_1.generateToken)();
131
131
  yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).updateOne({ email }, { $set: { token, tokenId, email, createdAt: new Date() } }, { upsert: true }));
132
132
  if (resetPasswordConfig.runResetFunction && resetPasswordConfig.resetFunctionName) {
133
- const functionsList = state_1.StateManager.select("functions");
134
- const services = state_1.StateManager.select("services");
133
+ const functionsList = state_1.StateManager.select('functions');
134
+ const services = state_1.StateManager.select('services');
135
135
  const currentFunction = functionsList[resetPasswordConfig.resetFunctionName];
136
136
  yield (0, context_1.GenerateContext)({
137
137
  args: [{ token, tokenId, email }],
@@ -155,12 +155,12 @@ function localUserPassController(app) {
155
155
  });
156
156
  });
157
157
  /**
158
- * Endpoint for confirm reset password.
159
- *
160
- * @route {POST} /reset
161
- * @param {ConfirmResetPasswordDto} req - The request object with reset data.
162
- * @returns {Promise<void>}
163
- */
158
+ * Endpoint for confirm reset password.
159
+ *
160
+ * @route {POST} /reset
161
+ * @param {ConfirmResetPasswordDto} req - The request object with reset data.
162
+ * @returns {Promise<void>}
163
+ */
164
164
  app.post(utils_1.AUTH_ENDPOINTS.CONFIRM_RESET, {
165
165
  schema: utils_1.CONFIRM_RESET_SCHEMA
166
166
  }, function (req) {
@@ -172,7 +172,7 @@ function localUserPassController(app) {
172
172
  throw new Error(utils_1.AUTH_ERRORS.INVALID_RESET_PARAMS);
173
173
  }
174
174
  const hashedPassword = yield (0, crypto_1.hashPassword)(password);
175
- yield db.collection(authCollection).updateOne({ email: resetRequest.email, }, {
175
+ yield db.collection(authCollection).updateOne({ email: resetRequest.email }, {
176
176
  $set: {
177
177
  password: hashedPassword
178
178
  }
@@ -63,7 +63,8 @@ export declare enum AUTH_ENDPOINTS {
63
63
  PROFILE = "/profile",
64
64
  SESSION = "/session",
65
65
  RESET = "/reset/call",
66
- CONFIRM_RESET = "/reset"
66
+ CONFIRM_RESET = "/reset",
67
+ FIRST_USER = "/setup/first-user"
67
68
  }
68
69
  export declare enum AUTH_ERRORS {
69
70
  INVALID_CREDENTIALS = "Invalid credentials",
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAGD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAUhC,CAAA;AAGD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,aAAa,WAAW;CACzB;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;CAChC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mBAAmB,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAEjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAErC,CAAA;AAID,eAAO,MAAM,aAAa,GAAI,qBAAqB,MAAM,EAAE,OAAO,MAAM,EAAE,SAAS,MAAM;;;;;CAyCxF,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;CAChC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mBAAmB,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAED,eAAO,MAAM,aAAa,GACxB,qBAAqB,MAAM,EAC3B,OAAO,MAAM,EACb,SAAS,MAAM;;;;;CA4ChB,CAAA"}