@lowdefy/connection-mongodb 5.4.0 → 5.5.0

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 (33) hide show
  1. package/dist/auth/adapters/MultiAppMongoDBAdapter/MultiAppMongoDBAdapter.js +155 -0
  2. package/dist/auth/adapters/MultiAppMongoDBAdapter/createDatabaseUser.js +39 -0
  3. package/dist/auth/adapters/MultiAppMongoDBAdapter/createDatabaseUserFromContact.js +63 -0
  4. package/dist/auth/adapters/MultiAppMongoDBAdapter/createDatabaseUserWithoutContact.js +59 -0
  5. package/dist/auth/adapters/MultiAppMongoDBAdapter/getUserFromDbByEmail.js +28 -0
  6. package/dist/auth/adapters/MultiAppMongoDBAdapter/getUserFromDbById.js +28 -0
  7. package/dist/auth/adapters/MultiAppMongoDBAdapter/transformContactToAdapterUser.js +29 -0
  8. package/dist/auth/adapters/MultiAppMongoDBAdapter/updateDatabaseUser.js +26 -0
  9. package/dist/auth/adapters.js +2 -1
  10. package/dist/connections/MongoDBCollection/MongoDBAggregation/MongoDBAggregation.js +3 -10
  11. package/dist/connections/MongoDBCollection/MongoDBBulkWrite/MongoDBBulkWrite.js +2 -9
  12. package/dist/connections/MongoDBCollection/MongoDBCollection.js +7 -1
  13. package/dist/connections/MongoDBCollection/MongoDBDeleteMany/MongoDBDeleteMany.js +19 -9
  14. package/dist/connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js +30 -7
  15. package/dist/connections/MongoDBCollection/MongoDBFind/MongoDBFind.js +3 -10
  16. package/dist/connections/MongoDBCollection/MongoDBFindOne/MongoDBFindOne.js +2 -9
  17. package/dist/connections/MongoDBCollection/MongoDBInsertConsecutiveId/MongoDBInsertConsecutiveId.js +84 -0
  18. package/dist/connections/MongoDBCollection/MongoDBInsertConsecutiveId/schema.js +60 -0
  19. package/dist/connections/MongoDBCollection/MongoDBInsertMany/MongoDBInsertMany.js +22 -11
  20. package/dist/connections/MongoDBCollection/MongoDBInsertManyConsecutiveIds/MongoDBInsertManyConsecutiveIds.js +86 -0
  21. package/dist/connections/MongoDBCollection/MongoDBInsertManyConsecutiveIds/schema.js +66 -0
  22. package/dist/connections/MongoDBCollection/MongoDBInsertOne/MongoDBInsertOne.js +19 -9
  23. package/dist/connections/MongoDBCollection/MongoDBUpdateMany/MongoDBUpdateMany.js +20 -9
  24. package/dist/connections/MongoDBCollection/MongoDBUpdateOne/MongoDBUpdateOne.js +48 -8
  25. package/dist/connections/MongoDBCollection/MongoDBUpdateOne/schema.js +7 -0
  26. package/dist/connections/MongoDBCollection/MongoDBVersionedUpdateOne/MongoDBVersionedUpdateOne.js +96 -0
  27. package/dist/connections/MongoDBCollection/MongoDBVersionedUpdateOne/schema.js +86 -0
  28. package/dist/connections/MongoDBCollection/getClient.js +44 -0
  29. package/dist/connections/MongoDBCollection/getCollection.js +18 -20
  30. package/dist/connections/MongoDBCollection/getConsecutiveIdIndex.js +50 -0
  31. package/dist/connections/MongoDBCollection/schema.js +29 -0
  32. package/dist/types.js +6 -2
  33. package/package.json +5 -4
@@ -0,0 +1,155 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import { MongoClient } from 'mongodb';
16
+ import createDatabaseUser from './createDatabaseUser.js';
17
+ import getUserFromDbByEmail from './getUserFromDbByEmail.js';
18
+ import getUserFromDbById from './getUserFromDbById.js';
19
+ import updateDatabaseUser from './updateDatabaseUser.js';
20
+ function from({ _id, ...data }) {
21
+ return {
22
+ id: _id,
23
+ ...data
24
+ };
25
+ }
26
+ function to({ id, ...data }) {
27
+ return {
28
+ _id: id,
29
+ ...data
30
+ };
31
+ }
32
+ function MultiAppMongoDBAdapter({ properties }) {
33
+ const { appName, collections, databaseUri, mongoDBClientOptions } = properties;
34
+ const mongoClient = new MongoClient(databaseUri, mongoDBClientOptions);
35
+ const collectionNames = {
36
+ accounts: collections?.accounts ?? 'user-accounts',
37
+ contacts: collections?.contacts ?? 'user-contacts',
38
+ sessions: collections?.sessions ?? 'user-sessions',
39
+ verificationTokens: collections?.verificationTokens ?? 'user-verification-tokens'
40
+ };
41
+ return {
42
+ async createUser (adapterUserData) {
43
+ return createDatabaseUser({
44
+ adapterUserData,
45
+ appName,
46
+ collectionNames,
47
+ inviteRequired: properties.invite?.required,
48
+ mongoClient
49
+ });
50
+ },
51
+ async getUser (userId) {
52
+ return getUserFromDbById({
53
+ appName,
54
+ collectionNames,
55
+ mongoClient,
56
+ userId
57
+ });
58
+ },
59
+ async getUserByEmail (email) {
60
+ return getUserFromDbByEmail({
61
+ appName,
62
+ collectionNames,
63
+ mongoClient,
64
+ email
65
+ });
66
+ },
67
+ async getUserByAccount (provider_providerAccountId) {
68
+ const account = await mongoClient.db().collection(collectionNames.accounts).findOne(provider_providerAccountId);
69
+ if (!account) return null;
70
+ return getUserFromDbById({
71
+ appName,
72
+ collectionNames,
73
+ mongoClient,
74
+ userId: account.userId
75
+ });
76
+ },
77
+ async updateUser (adapterUserData) {
78
+ await updateDatabaseUser({
79
+ adapterUserData,
80
+ collectionNames,
81
+ mongoClient
82
+ });
83
+ return adapterUserData;
84
+ },
85
+ // This is not yet implemented by Auth.js
86
+ // and we want to set a disabled flag, not delete users
87
+ // async deleteUser(userId) {
88
+ // await Promise.all([
89
+ // db.accounts.deleteMany({ userId }),
90
+ // db.sessions.deleteMany({ userId }),
91
+ // deleteDatabaseUser({ userId }),
92
+ // ]);
93
+ // },
94
+ async linkAccount (account) {
95
+ await mongoClient.db().collection(collectionNames.accounts).insertOne(to(account));
96
+ return from(account);
97
+ },
98
+ async unlinkAccount (provider_providerAccountId) {
99
+ const account = await mongoClient.db().collection(collectionNames.accounts).findOneAndDelete(provider_providerAccountId);
100
+ return from(account);
101
+ },
102
+ async getSessionAndUser (sessionToken) {
103
+ // eslint-disable-next-line no-unused-vars
104
+ const session = await mongoClient.db().collection(collectionNames.sessions).findOne({
105
+ sessionToken
106
+ });
107
+ if (!session) return null;
108
+ const user = await getUserFromDbById({
109
+ appName,
110
+ collectionNames,
111
+ mongoClient,
112
+ userId: session.userId
113
+ });
114
+ return {
115
+ user,
116
+ session: from(session)
117
+ };
118
+ },
119
+ async createSession (session) {
120
+ await mongoClient.db().collection(collectionNames.sessions).insertOne(to(session));
121
+ return session;
122
+ },
123
+ async updateSession (data) {
124
+ // eslint-disable-next-line no-unused-vars
125
+ const { _id, ...session } = to(data);
126
+ const result = await mongoClient.db().collection(collectionNames.sessions).findOneAndUpdate({
127
+ sessionToken: session.sessionToken
128
+ }, {
129
+ $set: session
130
+ }, {
131
+ returnDocument: 'after'
132
+ });
133
+ return from(result);
134
+ },
135
+ async deleteSession (sessionToken) {
136
+ const session = await mongoClient.db().collection(collectionNames.sessions).findOneAndDelete({
137
+ sessionToken
138
+ });
139
+ return from(session);
140
+ },
141
+ async createVerificationToken (data) {
142
+ const tokens = Array.from({
143
+ length: properties?.verificationTokens?.uses ?? 1
144
+ }, ()=>to(data));
145
+ await mongoClient.db().collection(collectionNames.verificationTokens).insertMany(tokens);
146
+ return data;
147
+ },
148
+ async useVerificationToken (identifier_token) {
149
+ const verificationToken = await mongoClient.db().collection(collectionNames.verificationTokens).findOneAndDelete(identifier_token);
150
+ if (!verificationToken) return null;
151
+ return from(verificationToken);
152
+ }
153
+ };
154
+ }
155
+ export default MultiAppMongoDBAdapter;
@@ -0,0 +1,39 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import createDatabaseUserFromContact from './createDatabaseUserFromContact.js';
16
+ import createDatabaseUserWithoutContact from './createDatabaseUserWithoutContact.js';
17
+ async function createDatabaseUser({ adapterUserData, appName, collectionNames, inviteRequired, mongoClient }) {
18
+ const contact = await mongoClient.db().collection(collectionNames.contacts).findOne({
19
+ lowercase_email: adapterUserData.email.toLowerCase()
20
+ });
21
+ if (contact) {
22
+ return createDatabaseUserFromContact({
23
+ adapterUserData,
24
+ appName,
25
+ collectionNames,
26
+ contact,
27
+ inviteRequired,
28
+ mongoClient
29
+ });
30
+ }
31
+ return createDatabaseUserWithoutContact({
32
+ adapterUserData,
33
+ appName,
34
+ collectionNames,
35
+ inviteRequired,
36
+ mongoClient
37
+ });
38
+ }
39
+ export default createDatabaseUser;
@@ -0,0 +1,63 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import transformContactToAdapterUser from './transformContactToAdapterUser.js';
16
+ async function createDatabaseUserFromContact({ adapterUserData, appName, collectionNames, contact, inviteRequired, mongoClient }) {
17
+ const invite = contact.apps?.[appName]?.invite;
18
+ if (inviteRequired && (!invite || !invite.open)) {
19
+ throw new Error('Access denied.');
20
+ }
21
+ if (contact.disabled || contact.removed || contact.apps?.[appName]?.disabled) {
22
+ throw new Error('Access denied.');
23
+ }
24
+ const { emailVerified: email_verified, image } = adapterUserData;
25
+ const update = {
26
+ email_verified,
27
+ image,
28
+ updated: {
29
+ timestamp: new Date(),
30
+ user: {
31
+ id: contact._id
32
+ }
33
+ }
34
+ };
35
+ if (contact.apps?.[appName]) {
36
+ update[`apps.${appName}.disabled`] = false;
37
+ update[`apps.${appName}.is_user`] = true;
38
+ update[`apps.${appName}.sign_up`] = new Date();
39
+ if (invite) {
40
+ update[`apps.${appName}.invite.open`] = false;
41
+ }
42
+ } else {
43
+ update[`apps.${appName}`] = {
44
+ app_attributes: {},
45
+ disabled: false,
46
+ is_user: true,
47
+ roles: [],
48
+ sign_up: new Date()
49
+ };
50
+ }
51
+ const updatedContact = await mongoClient.db().collection(collectionNames.contacts).findOneAndUpdate({
52
+ _id: contact._id
53
+ }, {
54
+ $set: update
55
+ }, {
56
+ returnDocument: 'after'
57
+ });
58
+ return transformContactToAdapterUser({
59
+ appName,
60
+ contact: updatedContact
61
+ });
62
+ }
63
+ export default createDatabaseUserFromContact;
@@ -0,0 +1,59 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import { v4 as uuid } from 'uuid';
16
+ import transformContactToAdapterUser from './transformContactToAdapterUser.js';
17
+ async function createDatabaseUserWithoutContact({ adapterUserData, appName, collectionNames, inviteRequired, mongoClient }) {
18
+ if (inviteRequired) {
19
+ throw new Error('Access denied.');
20
+ }
21
+ const { email, emailVerified: email_verified, image = null } = adapterUserData;
22
+ const contact = {
23
+ _id: uuid(),
24
+ email,
25
+ email_verified,
26
+ global_attributes: {},
27
+ image,
28
+ lowercase_email: email.toLowerCase(),
29
+ profile: {},
30
+ disabled: false,
31
+ apps: {
32
+ [appName]: {
33
+ app_attributes: {},
34
+ disabled: false,
35
+ is_user: true,
36
+ roles: [],
37
+ sign_up: new Date()
38
+ }
39
+ }
40
+ };
41
+ contact.created = {
42
+ timestamp: new Date(),
43
+ user: {
44
+ id: contact._id
45
+ }
46
+ };
47
+ contact.updated = {
48
+ timestamp: new Date(),
49
+ user: {
50
+ id: contact._id
51
+ }
52
+ };
53
+ await mongoClient.db().collection(collectionNames.contacts).insertOne(contact);
54
+ return transformContactToAdapterUser({
55
+ appName,
56
+ contact
57
+ });
58
+ }
59
+ export default createDatabaseUserWithoutContact;
@@ -0,0 +1,28 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import transformContactToAdapterUser from './transformContactToAdapterUser.js';
16
+ async function getUserFromDbByEmail({ appName, collectionNames, email, mongoClient }) {
17
+ const contact = await mongoClient.db().collection(collectionNames.contacts).findOne({
18
+ lowercase_email: email.toLowerCase()
19
+ });
20
+ if (!contact || contact.disabled || contact.removed || !contact.apps?.[appName]?.is_user || contact.apps?.[appName]?.disabled) {
21
+ return null;
22
+ }
23
+ return transformContactToAdapterUser({
24
+ appName,
25
+ contact
26
+ });
27
+ }
28
+ export default getUserFromDbByEmail;
@@ -0,0 +1,28 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import transformContactToAdapterUser from './transformContactToAdapterUser.js';
16
+ async function getUserFromDbById({ appName, collectionNames, mongoClient, userId }) {
17
+ const contact = await mongoClient.db().collection(collectionNames.contacts).findOne({
18
+ _id: userId
19
+ });
20
+ if (!contact || contact.disabled || contact.removed || !contact.apps?.[appName]?.is_user || contact.apps?.[appName]?.disabled) {
21
+ return null;
22
+ }
23
+ return transformContactToAdapterUser({
24
+ appName,
25
+ contact
26
+ });
27
+ }
28
+ export default getUserFromDbById;
@@ -0,0 +1,29 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ async function transformContactToAdapterUser({ appName, contact }) {
16
+ const { _id: id, email, email_verified: emailVerified = null, global_attributes = {}, image = null, profile = {} } = contact;
17
+ const { app_attributes, roles } = contact.apps[appName];
18
+ return {
19
+ id,
20
+ app_attributes,
21
+ email,
22
+ emailVerified,
23
+ image,
24
+ profile,
25
+ roles,
26
+ global_attributes
27
+ };
28
+ }
29
+ export default transformContactToAdapterUser;
@@ -0,0 +1,26 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ async function updateDatabaseUser({ adapterUserData, collectionNames, mongoClient }) {
16
+ const { emailVerified: email_verified, id, image } = adapterUserData;
17
+ await mongoClient.db().collection(collectionNames.contacts).updateOne({
18
+ _id: id
19
+ }, {
20
+ $set: {
21
+ email_verified,
22
+ image
23
+ }
24
+ });
25
+ }
26
+ export default updateDatabaseUser;
@@ -1,2 +1,3 @@
1
1
  import MongoDBAdapter from './adapters/MongoDBAdapter/MongoDBAdapter.js';
2
- export { MongoDBAdapter };
2
+ import MultiAppMongoDBAdapter from './adapters/MultiAppMongoDBAdapter/MultiAppMongoDBAdapter.js';
3
+ export { MongoDBAdapter, MultiAppMongoDBAdapter };
@@ -31,18 +31,11 @@ async function MongodbAggregation({ request, connection }) {
31
31
  pipeline,
32
32
  connection
33
33
  });
34
- const { collection, client } = await getCollection({
34
+ const { collection } = await getCollection({
35
35
  connection
36
36
  });
37
- let res;
38
- try {
39
- const cursor = await collection.aggregate(pipeline, options);
40
- res = await cursor.toArray();
41
- } catch (error) {
42
- await client.close();
43
- throw error;
44
- }
45
- await client.close();
37
+ const cursor = await collection.aggregate(pipeline, options);
38
+ const res = await cursor.toArray();
46
39
  return serialize(res);
47
40
  }
48
41
  MongodbAggregation.schema = schema;
@@ -18,17 +18,10 @@ import schema from './schema.js';
18
18
  async function MongodbBulkWrite({ connection, request }) {
19
19
  const deserializedRequest = deserialize(request);
20
20
  const { operations, options } = deserializedRequest;
21
- const { collection, client } = await getCollection({
21
+ const { collection } = await getCollection({
22
22
  connection
23
23
  });
24
- let response;
25
- try {
26
- response = await collection.bulkWrite(operations, options);
27
- } catch (error) {
28
- await client.close();
29
- throw error;
30
- }
31
- await client.close();
24
+ const response = await collection.bulkWrite(operations, options);
32
25
  return serialize(response);
33
26
  }
34
27
  MongodbBulkWrite.schema = schema;
@@ -18,10 +18,13 @@ import MongoDBDeleteMany from './MongoDBDeleteMany/MongoDBDeleteMany.js';
18
18
  import MongoDBDeleteOne from './MongoDBDeleteOne/MongoDBDeleteOne.js';
19
19
  import MongoDBFind from './MongoDBFind/MongoDBFind.js';
20
20
  import MongoDBFindOne from './MongoDBFindOne/MongoDBFindOne.js';
21
+ import MongoDBInsertConsecutiveId from './MongoDBInsertConsecutiveId/MongoDBInsertConsecutiveId.js';
21
22
  import MongoDBInsertMany from './MongoDBInsertMany/MongoDBInsertMany.js';
23
+ import MongoDBInsertManyConsecutiveIds from './MongoDBInsertManyConsecutiveIds/MongoDBInsertManyConsecutiveIds.js';
22
24
  import MongoDBInsertOne from './MongoDBInsertOne/MongoDBInsertOne.js';
23
25
  import MongoDBUpdateMany from './MongoDBUpdateMany/MongoDBUpdateMany.js';
24
26
  import MongoDBUpdateOne from './MongoDBUpdateOne/MongoDBUpdateOne.js';
27
+ import MongoDBVersionedUpdateOne from './MongoDBVersionedUpdateOne/MongoDBVersionedUpdateOne.js';
25
28
  import schema from './schema.js';
26
29
  export default {
27
30
  schema,
@@ -32,9 +35,12 @@ export default {
32
35
  MongoDBDeleteOne,
33
36
  MongoDBFind,
34
37
  MongoDBFindOne,
38
+ MongoDBInsertConsecutiveId,
35
39
  MongoDBInsertMany,
40
+ MongoDBInsertManyConsecutiveIds,
36
41
  MongoDBInsertOne,
37
42
  MongoDBUpdateMany,
38
- MongoDBUpdateOne
43
+ MongoDBUpdateOne,
44
+ MongoDBVersionedUpdateOne
39
45
  }
40
46
  };
@@ -15,20 +15,30 @@
15
15
  */ import getCollection from '../getCollection.js';
16
16
  import { serialize, deserialize } from '../serialize.js';
17
17
  import schema from './schema.js';
18
- async function MongodbDeleteMany({ connection, request }) {
18
+ async function MongodbDeleteMany({ blockId, connection, connectionId, pageId, payload, request, requestId }) {
19
19
  const deserializedRequest = deserialize(request);
20
20
  const { filter, options } = deserializedRequest;
21
- const { collection, client } = await getCollection({
21
+ const { collection, logCollection } = await getCollection({
22
22
  connection
23
23
  });
24
- let response;
25
- try {
26
- response = await collection.deleteMany(filter, options);
27
- } catch (error) {
28
- await client.close();
29
- throw error;
24
+ const response = await collection.deleteMany(filter, options);
25
+ if (logCollection) {
26
+ await logCollection.insertOne({
27
+ args: {
28
+ filter,
29
+ options
30
+ },
31
+ blockId,
32
+ connectionId,
33
+ pageId,
34
+ payload,
35
+ requestId,
36
+ response,
37
+ timestamp: new Date(),
38
+ type: 'MongoDBDeleteMany',
39
+ meta: connection.changeLog?.meta
40
+ });
30
41
  }
31
- await client.close();
32
42
  const { acknowledged, deletedCount } = serialize(response);
33
43
  return {
34
44
  acknowledged,
@@ -15,20 +15,43 @@
15
15
  */ import getCollection from '../getCollection.js';
16
16
  import { serialize, deserialize } from '../serialize.js';
17
17
  import schema from './schema.js';
18
- async function MongodbDeleteOne({ connection, request }) {
18
+ async function MongodbDeleteOne({ blockId, connection, connectionId, pageId, payload, request, requestId }) {
19
19
  const deserializedRequest = deserialize(request);
20
20
  const { filter, options } = deserializedRequest;
21
- const { collection, client } = await getCollection({
21
+ const { collection, logCollection } = await getCollection({
22
22
  connection
23
23
  });
24
24
  let response;
25
- try {
25
+ if (logCollection) {
26
+ // findOneAndDelete instead of deleteOne to capture the deleted document
27
+ // for the change log. The response shape matches the deleteOne response.
28
+ const result = await collection.findOneAndDelete(filter, {
29
+ ...options,
30
+ includeResultMetadata: true
31
+ });
32
+ const before = result.value ?? null;
33
+ response = {
34
+ acknowledged: true,
35
+ deletedCount: result.lastErrorObject?.n ?? 0
36
+ };
37
+ await logCollection.insertOne({
38
+ args: {
39
+ filter,
40
+ options
41
+ },
42
+ blockId,
43
+ connectionId,
44
+ pageId,
45
+ payload,
46
+ requestId,
47
+ before,
48
+ timestamp: new Date(),
49
+ type: 'MongoDBDeleteOne',
50
+ meta: connection.changeLog?.meta
51
+ });
52
+ } else {
26
53
  response = await collection.deleteOne(filter, options);
27
- } catch (error) {
28
- await client.close();
29
- throw error;
30
54
  }
31
- await client.close();
32
55
  return serialize(response);
33
56
  }
34
57
  MongodbDeleteOne.schema = schema;
@@ -18,18 +18,11 @@ import schema from './schema.js';
18
18
  async function MongodbFind({ request, connection }) {
19
19
  const deserializedRequest = deserialize(request);
20
20
  const { query, options } = deserializedRequest;
21
- const { collection, client } = await getCollection({
21
+ const { collection } = await getCollection({
22
22
  connection
23
23
  });
24
- let res;
25
- try {
26
- const cursor = await collection.find(query, options);
27
- res = await cursor.toArray();
28
- } catch (error) {
29
- await client.close();
30
- throw error;
31
- }
32
- await client.close();
24
+ const cursor = await collection.find(query, options);
25
+ const res = await cursor.toArray();
33
26
  return serialize(res);
34
27
  }
35
28
  MongodbFind.schema = schema;
@@ -18,17 +18,10 @@ import schema from './schema.js';
18
18
  async function MongodbFindOne({ request, connection }) {
19
19
  const deserializedRequest = deserialize(request);
20
20
  const { query, options } = deserializedRequest;
21
- const { collection, client } = await getCollection({
21
+ const { collection } = await getCollection({
22
22
  connection
23
23
  });
24
- let res;
25
- try {
26
- res = await collection.findOne(query, options);
27
- } catch (error) {
28
- await client.close();
29
- throw error;
30
- }
31
- await client.close();
24
+ const res = await collection.findOne(query, options);
32
25
  return serialize(res);
33
26
  }
34
27
  MongodbFindOne.schema = schema;