@timardex/cluemart-server-shared 1.0.148 → 1.0.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Chat-CM_mGOB0.d.mts → Chat-Ctmtatmi.d.mts} +2 -13
- package/dist/{Chat-CM_mGOB0.d.ts → Chat-Ctmtatmi.d.ts} +2 -13
- package/dist/{chunk-XT6SQI4D.mjs → chunk-YNM5IJGO.mjs} +4 -2
- package/dist/chunk-YNM5IJGO.mjs.map +1 -0
- package/dist/index.cjs +109 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -14
- package/dist/index.d.ts +3 -14
- package/dist/index.mjs +109 -37
- package/dist/index.mjs.map +1 -1
- package/dist/mongoose/index.cjs +2 -2
- package/dist/mongoose/index.cjs.map +1 -1
- package/dist/mongoose/index.d.mts +3 -3
- package/dist/mongoose/index.d.ts +3 -3
- package/dist/mongoose/index.mjs +1 -3
- package/dist/service/index.cjs +107 -34
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.mts +1 -1
- package/dist/service/index.d.ts +1 -1
- package/dist/service/index.mjs +108 -35
- package/dist/service/index.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.mts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-XT6SQI4D.mjs.map +0 -1
package/dist/service/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-
|
|
1
|
+
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-Ctmtatmi.mjs';
|
|
2
2
|
import { EnumUserLicence } from '@timardex/cluemart-shared';
|
|
3
3
|
import 'mongoose';
|
|
4
4
|
import '@timardex/cluemart-shared/types';
|
package/dist/service/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-
|
|
1
|
+
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-Ctmtatmi.js';
|
|
2
2
|
import { EnumUserLicence } from '@timardex/cluemart-shared';
|
|
3
3
|
import 'mongoose';
|
|
4
4
|
import '@timardex/cluemart-shared/types';
|
package/dist/service/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AdModel,
|
|
3
|
+
ChatModel,
|
|
3
4
|
EnumAdStatus,
|
|
5
|
+
EnumChatType,
|
|
4
6
|
EnumResourceType,
|
|
5
7
|
EnumUserLicence,
|
|
6
8
|
EventModel,
|
|
@@ -9,7 +11,7 @@ import {
|
|
|
9
11
|
PushTokenModel,
|
|
10
12
|
UserModel,
|
|
11
13
|
VendorModel
|
|
12
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-YNM5IJGO.mjs";
|
|
13
15
|
import "../chunk-3QS3WKRC.mjs";
|
|
14
16
|
|
|
15
17
|
// src/service/database.ts
|
|
@@ -204,10 +206,44 @@ async function updateAdStatuses() {
|
|
|
204
206
|
);
|
|
205
207
|
}
|
|
206
208
|
|
|
209
|
+
// src/service/vendor.ts
|
|
210
|
+
import mongoose3 from "mongoose";
|
|
211
|
+
|
|
207
212
|
// src/service/associate.ts
|
|
208
|
-
|
|
213
|
+
import mongoose2 from "mongoose";
|
|
214
|
+
async function removeAssociateFromResource({
|
|
215
|
+
resourceId,
|
|
216
|
+
resourceOwnerId,
|
|
217
|
+
resourceType
|
|
218
|
+
}) {
|
|
209
219
|
const normalizedResourceId = resourceId.toString();
|
|
220
|
+
const normalizedOwnerId = typeof resourceOwnerId === "string" ? new mongoose2.Types.ObjectId(resourceOwnerId) : resourceOwnerId;
|
|
221
|
+
const session = await mongoose2.startSession();
|
|
210
222
|
try {
|
|
223
|
+
session.startTransaction();
|
|
224
|
+
const usersWithAssociates = await UserModel.find(
|
|
225
|
+
{
|
|
226
|
+
associates: {
|
|
227
|
+
$elemMatch: {
|
|
228
|
+
resourceId: normalizedResourceId,
|
|
229
|
+
resourceType
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
associates: 1
|
|
235
|
+
// Only fetch associates field for efficiency
|
|
236
|
+
}
|
|
237
|
+
).lean().session(session);
|
|
238
|
+
const associateEmails = usersWithAssociates.flatMap(
|
|
239
|
+
(user) => (user.associates ?? []).filter(
|
|
240
|
+
(assoc) => assoc.resourceId === normalizedResourceId && assoc.resourceType === resourceType
|
|
241
|
+
).map((assoc) => assoc.email)
|
|
242
|
+
);
|
|
243
|
+
if (associateEmails.length === 0) {
|
|
244
|
+
await session.commitTransaction();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
211
247
|
await UserModel.updateMany(
|
|
212
248
|
{
|
|
213
249
|
associates: {
|
|
@@ -224,34 +260,67 @@ async function removeAssociateFromResource(resourceId, resourceType) {
|
|
|
224
260
|
resourceType
|
|
225
261
|
}
|
|
226
262
|
}
|
|
263
|
+
},
|
|
264
|
+
{ session }
|
|
265
|
+
);
|
|
266
|
+
await ChatModel.updateMany(
|
|
267
|
+
{
|
|
268
|
+
active: true,
|
|
269
|
+
chatType: EnumChatType.RELATION,
|
|
270
|
+
deletedAt: null,
|
|
271
|
+
participants: {
|
|
272
|
+
$elemMatch: {
|
|
273
|
+
userId: normalizedOwnerId
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
$set: {
|
|
279
|
+
"participants.$[assoc].active": false
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
arrayFilters: [
|
|
284
|
+
{
|
|
285
|
+
"assoc.isAssociate": true,
|
|
286
|
+
"assoc.userEmail": { $in: associateEmails }
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
session
|
|
227
290
|
}
|
|
228
|
-
)
|
|
291
|
+
);
|
|
292
|
+
await session.commitTransaction();
|
|
229
293
|
} catch (error) {
|
|
294
|
+
await session.abortTransaction();
|
|
230
295
|
console.error(
|
|
231
|
-
`[removeAssociateFromResource] Failed
|
|
296
|
+
`[removeAssociateFromResource] Failed for resourceId=${normalizedResourceId}, resourceType=${resourceType}`,
|
|
232
297
|
error
|
|
233
298
|
);
|
|
234
299
|
throw error;
|
|
300
|
+
} finally {
|
|
301
|
+
session.endSession();
|
|
235
302
|
}
|
|
236
303
|
}
|
|
237
304
|
|
|
238
305
|
// src/service/vendor.ts
|
|
239
306
|
async function updateVendorBasedOnUserLicense(userId, licenceType) {
|
|
307
|
+
const session = await mongoose3.startSession();
|
|
240
308
|
try {
|
|
241
|
-
|
|
242
|
-
|
|
309
|
+
session.startTransaction();
|
|
310
|
+
const user = await UserModel.findById(userId).select("vendor").lean().session(session);
|
|
311
|
+
if (!user?.vendor) {
|
|
312
|
+
console.warn(`[updateVendor] No vendor for userId=${userId}`);
|
|
313
|
+
await session.abortTransaction();
|
|
243
314
|
return;
|
|
244
315
|
}
|
|
245
|
-
const
|
|
246
|
-
if (!
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const selectedLicence = licenceType;
|
|
250
|
-
if (selectedLicence === void 0) {
|
|
316
|
+
const vendor = await VendorModel.findById(user.vendor).lean().session(session);
|
|
317
|
+
if (!vendor) {
|
|
318
|
+
console.warn(`[updateVendor] Vendor not found for id=${user.vendor}`);
|
|
319
|
+
await session.abortTransaction();
|
|
251
320
|
return;
|
|
252
321
|
}
|
|
253
322
|
const vendorUpdateData = {};
|
|
254
|
-
if (
|
|
323
|
+
if (licenceType === EnumUserLicence.STANDARD_VENDOR) {
|
|
255
324
|
vendorUpdateData.associates = [];
|
|
256
325
|
vendorUpdateData.availability = {
|
|
257
326
|
corporate: false,
|
|
@@ -260,46 +329,50 @@ async function updateVendorBasedOnUserLicense(userId, licenceType) {
|
|
|
260
329
|
};
|
|
261
330
|
vendorUpdateData.products = {
|
|
262
331
|
active: false,
|
|
263
|
-
productsList:
|
|
332
|
+
productsList: vendor.products?.productsList ?? []
|
|
264
333
|
};
|
|
265
334
|
vendorUpdateData.calendar = {
|
|
266
335
|
active: false,
|
|
267
|
-
calendarData:
|
|
336
|
+
calendarData: vendor.calendar?.calendarData ?? []
|
|
268
337
|
};
|
|
269
|
-
vendorUpdateData.images = (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
source: img.source,
|
|
273
|
-
title: img.title
|
|
338
|
+
vendorUpdateData.images = (vendor.images ?? []).map((img, index) => ({
|
|
339
|
+
...img,
|
|
340
|
+
active: index < 6
|
|
274
341
|
}));
|
|
275
342
|
} else {
|
|
276
|
-
vendorUpdateData.images = (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
source: img.source,
|
|
280
|
-
title: img.title
|
|
343
|
+
vendorUpdateData.images = (vendor.images ?? []).map((img) => ({
|
|
344
|
+
...img,
|
|
345
|
+
active: true
|
|
281
346
|
}));
|
|
282
347
|
}
|
|
283
|
-
await VendorModel.
|
|
284
|
-
|
|
285
|
-
{
|
|
286
|
-
|
|
287
|
-
},
|
|
288
|
-
{ new: true }
|
|
348
|
+
await VendorModel.updateOne(
|
|
349
|
+
{ _id: vendor._id },
|
|
350
|
+
{ $set: vendorUpdateData },
|
|
351
|
+
{ session }
|
|
289
352
|
);
|
|
290
|
-
|
|
353
|
+
if (licenceType === EnumUserLicence.STANDARD_VENDOR) {
|
|
354
|
+
await removeAssociateFromResource({
|
|
355
|
+
resourceId: vendor._id,
|
|
356
|
+
resourceOwnerId: vendor.owner.userId,
|
|
357
|
+
resourceType: EnumResourceType.VENDOR
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
await session.commitTransaction();
|
|
291
361
|
} catch (error) {
|
|
292
|
-
|
|
362
|
+
await session.abortTransaction();
|
|
363
|
+
console.error("[updateVendorBasedOnUserLicense] Failed:", error);
|
|
364
|
+
} finally {
|
|
365
|
+
session.endSession();
|
|
293
366
|
}
|
|
294
367
|
}
|
|
295
368
|
|
|
296
369
|
// src/service/objectIdToString.ts
|
|
297
|
-
import
|
|
370
|
+
import mongoose4 from "mongoose";
|
|
298
371
|
function convertObjectIdsToStrings(obj) {
|
|
299
372
|
if (obj === null || obj === void 0) {
|
|
300
373
|
return obj;
|
|
301
374
|
}
|
|
302
|
-
if (obj instanceof
|
|
375
|
+
if (obj instanceof mongoose4.Types.ObjectId) {
|
|
303
376
|
return obj.toString();
|
|
304
377
|
}
|
|
305
378
|
if (Array.isArray(obj)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/service/database.ts","../../src/service/saveNotificationsInDb.ts","../../src/service/sendPushNotifications.ts","../../src/service/updateAdStatus.ts","../../src/service/associate.ts","../../src/service/vendor.ts","../../src/service/objectIdToString.ts","../../src/service/event.ts"],"sourcesContent":["import mongoose from \"mongoose\";\n\n/**\n * Connect to MongoDB using Mongoose.\n * Supports both local MongoDB (via MONGODB_URI) and MongoDB Atlas (via individual env vars).\n */\nexport const connectToDatabase = async ({\n appName,\n dbName,\n dbPassword,\n dbUser,\n mongodbUri,\n}: {\n appName: string;\n dbName: string;\n dbPassword: string;\n dbUser: string;\n mongodbUri: string;\n}) => {\n try {\n // Check if MONGODB_URI is provided (for local Docker MongoDB)\n const mongoUri = mongodbUri\n ? mongodbUri\n : // Fallback to MongoDB Atlas connection string\n `mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`;\n\n await mongoose.connect(mongoUri);\n\n const connectionType = mongodbUri ? \"Local MongoDB\" : \"MongoDB Atlas\";\n console.log(\n `${connectionType} connected from server/src/service/database.ts`,\n );\n } catch (err) {\n console.error(\"Error connecting to MongoDB:\", err);\n throw err; // You can throw the error if you want to stop the server in case of connection failure\n }\n};\n","import {\n SchemaCreateBulkNotificationInput,\n NotificationModel,\n} from \"src/mongoose/Notification\";\nimport { ObjectId } from \"src/types\";\n\n/**\n * Create notifications in the database for multiple users\n * This is typically called when sending push notifications\n */\nexport async function saveNotificationsInDb(\n payload: SchemaCreateBulkNotificationInput,\n): Promise<ObjectId[]> {\n const { data, message, title, type, userIds } = payload;\n try {\n const notifications = userIds.map((userId) => ({\n data,\n isRead: false,\n message,\n title,\n type,\n userId,\n }));\n\n // Save notifications to database\n await NotificationModel.insertMany(notifications);\n console.log(\n `Created ${notifications.length} notifications for ${userIds.length} users`,\n );\n\n return [...new Set(userIds)];\n } catch (error) {\n console.error(\"Failed to create notifications:\", error);\n return [];\n //throw new Error(`Failed to create notifications: ${error}`);\n }\n}\n","import { NotificationDataType } from \"@timardex/cluemart-shared\";\nimport { Expo, ExpoPushMessage, ExpoPushTicket } from \"expo-server-sdk\";\n\nimport { SchemaCreateBulkNotificationInput } from \"src/mongoose/Notification\";\nimport { PushTokenModel } from \"src/mongoose/PushToken\";\n\nconst expo = new Expo();\n\n/**\n * Safely extract tokens from ExpoPushMessage handling both string and array cases\n */\nfunction extractTokensFromMessage(message: ExpoPushMessage): string[] {\n return Array.isArray(message.to) ? message.to : [message.to];\n}\n\ninterface CreatePushMessagesOptions {\n tokens: string[];\n message: string;\n title: string;\n data: NotificationDataType;\n}\n\n/**\n * Create push messages from valid tokens\n */\nfunction createPushMessages({\n tokens,\n message,\n title,\n data,\n}: CreatePushMessagesOptions): {\n messages: ExpoPushMessage[];\n invalidTokens: string[];\n} {\n const messages: ExpoPushMessage[] = [];\n const invalidTokens: string[] = [];\n\n for (const token of tokens) {\n if (!Expo.isExpoPushToken(token)) {\n invalidTokens.push(token);\n continue;\n }\n\n messages.push({\n body: message,\n data: { ...data },\n sound: \"default\",\n title,\n to: token,\n });\n }\n\n return { invalidTokens, messages };\n}\n\n/**\n * Process chunk results and extract failed tokens\n */\nfunction processChunkResults(\n tickets: ExpoPushTicket[],\n chunk: ExpoPushMessage[],\n): { successCount: number; failedTokens: string[] } {\n let successCount = 0;\n const failedTokens: string[] = [];\n\n for (const [ticketIndex, ticket] of tickets.entries()) {\n if (ticket.status === \"error\") {\n const message = chunk[ticketIndex];\n if (message) {\n const tokens = extractTokensFromMessage(message);\n if (ticket.details?.error === \"DeviceNotRegistered\") {\n failedTokens.push(...tokens);\n }\n console.log(\"Push notification error\", {\n error: ticket.details?.error,\n tokens,\n });\n }\n } else {\n successCount++;\n }\n }\n\n return { failedTokens, successCount };\n}\n\n/**\n * Send a single chunk of push notifications\n */\nasync function sendChunk(\n chunk: ExpoPushMessage[],\n chunkIndex: number,\n): Promise<{ successCount: number; failedTokens: string[] }> {\n try {\n const tickets = await expo.sendPushNotificationsAsync(chunk);\n const { successCount, failedTokens } = processChunkResults(tickets, chunk);\n\n console.log(\n `Chunk ${chunkIndex + 1}: Sent ${successCount}/${chunk.length} notifications successfully`,\n );\n\n return { failedTokens, successCount };\n } catch (error) {\n console.log(\"Error sending Expo push notification chunk\", {\n chunkIndex,\n chunkSize: chunk.length,\n error: error instanceof Error ? error.message : String(error),\n });\n return { failedTokens: [], successCount: 0 };\n }\n}\n\nexport async function sendPushNotifications({\n data,\n message,\n title,\n userIds,\n}: SchemaCreateBulkNotificationInput) {\n const pushTokens = await PushTokenModel.find({ userId: { $in: userIds } });\n const expoTokens = pushTokens.map((token) => token.token);\n\n if (!data) return;\n\n const { messages, invalidTokens } = createPushMessages({\n data,\n message,\n title,\n tokens: expoTokens,\n });\n\n // Log invalid tokens\n if (invalidTokens.length > 0) {\n console.log(`Found ${invalidTokens.length} invalid push tokens`);\n }\n\n if (messages.length === 0) {\n console.log(\"No valid messages to send after filtering tokens\");\n return;\n }\n\n // Send notifications in chunks\n const chunks = expo.chunkPushNotifications(messages);\n let totalSuccessCount = 0;\n const allFailedTokens: string[] = [];\n\n for (const [chunkIndex, chunk] of chunks.entries()) {\n const { successCount, failedTokens } = await sendChunk(\n chunk,\n chunkIndex + 1,\n );\n totalSuccessCount += successCount;\n allFailedTokens.push(...failedTokens);\n }\n\n // Log final results\n console.log(\n `Sent push notification to ${totalSuccessCount}/${messages.length} tokens across ${chunks.length} chunks`,\n );\n\n if (allFailedTokens.length > 0) {\n console.log(`Found ${allFailedTokens.length} failed push tokens`);\n }\n}\n","import { EnumAdStatus } from \"@timardex/cluemart-shared\";\n\nimport { AdModel } from \"src/mongoose\";\n\n/**\n * Updates ad statuses based on start/end dates and validity\n */\nexport async function updateAdStatuses(): Promise<void> {\n const now = new Date();\n\n // invalid\n const invalidResult = await AdModel.updateMany(\n {\n $or: [\n { start: { $exists: false } },\n { end: { $exists: false } },\n { $expr: { $gt: [\"$start\", \"$end\"] } },\n ],\n status: { $ne: EnumAdStatus.PAUSED },\n },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n // expired\n const expiredResult = await AdModel.updateMany(\n { end: { $lte: now }, status: { $ne: EnumAdStatus.EXPIRED } },\n { $set: { status: EnumAdStatus.EXPIRED } },\n );\n\n // active\n const activeResult = await AdModel.updateMany(\n {\n end: { $gt: now },\n start: { $lte: now },\n status: { $ne: EnumAdStatus.ACTIVE },\n },\n { $set: { status: EnumAdStatus.ACTIVE } },\n );\n\n // paused\n const pausedResult = await AdModel.updateMany(\n { start: { $gt: now }, status: { $ne: EnumAdStatus.PAUSED } },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n console.log(\n `✅ Ad statuses updated: invalid=${invalidResult.modifiedCount}, expired=${expiredResult.modifiedCount}, active=${activeResult.modifiedCount}, paused=${pausedResult.modifiedCount}`,\n );\n}\n","import { EnumResourceType } from \"@timardex/cluemart-shared\";\n\nimport { UserModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\n/**\n * Removes all associate references for a specific resource\n * from every user document.\n *\n * Uses a single atomic update instead of loading + saving each user.\n */\nexport async function removeAssociateFromResource(\n resourceId: string | ObjectId,\n resourceType: EnumResourceType,\n): Promise<void> {\n const normalizedResourceId = resourceId.toString();\n try {\n await UserModel.updateMany(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n $pull: {\n associates: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n ).exec();\n } catch (error) {\n console.error(\n `[removeAssociateFromResource] Failed to remove associates for resourceId=${normalizedResourceId}, resourceType=${resourceType}`,\n error,\n );\n\n throw error;\n }\n}\n","import { EnumResourceType, EnumUserLicence } from \"@timardex/cluemart-shared\";\n\nimport { SchemaVendorType, UserModel, VendorModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { removeAssociateFromResource } from \"./associate\";\n\n/**\n *\n * This function updates the vendor's features based on the user's license.\n * It checks the type of license and updates the vendor's associates and availability accordingly.\n * If the user has a Pro Vendor license, they can have multiple associates and access to all availability types.\n * If they have a Standard Vendor license, their associates are removed and availability is restricted.\n * @param userId\n * @param licenceType\n * @returns\n */\nexport async function updateVendorBasedOnUserLicense(\n userId: ObjectId,\n licenceType: EnumUserLicence,\n) {\n try {\n const user = await UserModel.findById(userId).exec();\n\n if (!user) {\n return;\n }\n\n const userVendor = await VendorModel.findById(user.vendor).exec();\n\n if (!userVendor) {\n return;\n }\n\n const selectedLicence = licenceType;\n\n // Only update vendor features if selectedLicence is provided\n // This handles the case where selectedLicence might be undefined (e.g., in Stripe webhook cancellation)\n if (selectedLicence === undefined) {\n // If selectedLicence is undefined, we won't change the associates or availability\n return;\n }\n const vendorUpdateData: Partial<SchemaVendorType> = {};\n\n if (selectedLicence === EnumUserLicence.STANDARD_VENDOR) {\n vendorUpdateData.associates = [];\n vendorUpdateData.availability = {\n corporate: false,\n private: false,\n school: false,\n };\n vendorUpdateData.products = {\n active: false,\n productsList: userVendor.products?.productsList || [],\n };\n vendorUpdateData.calendar = {\n active: false,\n calendarData: userVendor.calendar?.calendarData || [],\n };\n vendorUpdateData.images = (userVendor.images || []).map((img, index) => ({\n active: index < 6, // first 6 will be true, the rest false\n source: img.source,\n title: img.title,\n }));\n } else {\n vendorUpdateData.images = (userVendor.images || []).map((img) => ({\n active: true, // all images will be true\n source: img.source,\n title: img.title,\n }));\n }\n\n await VendorModel.findByIdAndUpdate(\n userVendor._id,\n {\n $set: vendorUpdateData,\n },\n { new: true },\n );\n\n await removeAssociateFromResource(userVendor._id, EnumResourceType.VENDOR);\n } catch (error) {\n console.error(\"Error updating vendor based on user license:\", error);\n }\n}\n","import mongoose from \"mongoose\";\n\n/**\n * Recursively converts all ObjectId fields to strings in an object\n * This is needed because GraphQL expects string IDs, not ObjectIds\n */\nexport function convertObjectIdsToStrings(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (obj instanceof mongoose.Types.ObjectId) {\n return obj.toString();\n }\n\n if (Array.isArray(obj)) {\n return obj.map(convertObjectIdsToStrings);\n }\n\n if (typeof obj === \"object\") {\n const converted: any = {};\n for (const [key, value] of Object.entries(obj)) {\n converted[key] = convertObjectIdsToStrings(value);\n }\n return converted;\n }\n\n return obj;\n}\n","import { EventModel, GoogleImportedMarketModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { convertObjectIdsToStrings } from \"./objectIdToString\";\n\ntype EventOrMarket = { _id: ObjectId | string; name: string } | null;\n\n/**\n * This function attempts to find an Event or a Google Imported Market by the given resource ID.\n * It first normalizes the resource ID to a string format, then performs parallel queries to both collections.\n * If an Event is found, it returns that; otherwise, it checks for a Google Imported Market and returns it if found.\n * If neither is found, it returns null.\n * @param resourceId - The ID of the resource to find, which can be an ObjectId, string, null, or undefined.\n * @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.\n */\n\nexport async function findEventOrImportedMarketById(\n resourceId: ObjectId | string | null | undefined,\n): Promise<EventOrMarket> {\n if (!resourceId) {\n return null;\n }\n\n const normalizedId = convertObjectIdsToStrings(resourceId) as string;\n\n const [eventDoc, googleImportedDoc] = await Promise.all([\n EventModel.findById(normalizedId).select(\"_id name\").lean().exec(),\n GoogleImportedMarketModel.findById(normalizedId)\n .select(\"_id name\")\n .lean()\n .exec(),\n ]);\n\n return eventDoc ?? googleImportedDoc;\n}\n"],"mappings":"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","names":["mongoose"]}
|
|
1
|
+
{"version":3,"sources":["../../src/service/database.ts","../../src/service/saveNotificationsInDb.ts","../../src/service/sendPushNotifications.ts","../../src/service/updateAdStatus.ts","../../src/service/vendor.ts","../../src/service/associate.ts","../../src/service/objectIdToString.ts","../../src/service/event.ts"],"sourcesContent":["import mongoose from \"mongoose\";\n\n/**\n * Connect to MongoDB using Mongoose.\n * Supports both local MongoDB (via MONGODB_URI) and MongoDB Atlas (via individual env vars).\n */\nexport const connectToDatabase = async ({\n appName,\n dbName,\n dbPassword,\n dbUser,\n mongodbUri,\n}: {\n appName: string;\n dbName: string;\n dbPassword: string;\n dbUser: string;\n mongodbUri: string;\n}) => {\n try {\n // Check if MONGODB_URI is provided (for local Docker MongoDB)\n const mongoUri = mongodbUri\n ? mongodbUri\n : // Fallback to MongoDB Atlas connection string\n `mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`;\n\n await mongoose.connect(mongoUri);\n\n const connectionType = mongodbUri ? \"Local MongoDB\" : \"MongoDB Atlas\";\n console.log(\n `${connectionType} connected from server/src/service/database.ts`,\n );\n } catch (err) {\n console.error(\"Error connecting to MongoDB:\", err);\n throw err; // You can throw the error if you want to stop the server in case of connection failure\n }\n};\n","import {\n SchemaCreateBulkNotificationInput,\n NotificationModel,\n} from \"src/mongoose/Notification\";\nimport { ObjectId } from \"src/types\";\n\n/**\n * Create notifications in the database for multiple users\n * This is typically called when sending push notifications\n */\nexport async function saveNotificationsInDb(\n payload: SchemaCreateBulkNotificationInput,\n): Promise<ObjectId[]> {\n const { data, message, title, type, userIds } = payload;\n try {\n const notifications = userIds.map((userId) => ({\n data,\n isRead: false,\n message,\n title,\n type,\n userId,\n }));\n\n // Save notifications to database\n await NotificationModel.insertMany(notifications);\n console.log(\n `Created ${notifications.length} notifications for ${userIds.length} users`,\n );\n\n return [...new Set(userIds)];\n } catch (error) {\n console.error(\"Failed to create notifications:\", error);\n return [];\n //throw new Error(`Failed to create notifications: ${error}`);\n }\n}\n","import { NotificationDataType } from \"@timardex/cluemart-shared\";\nimport { Expo, ExpoPushMessage, ExpoPushTicket } from \"expo-server-sdk\";\n\nimport { SchemaCreateBulkNotificationInput } from \"src/mongoose/Notification\";\nimport { PushTokenModel } from \"src/mongoose/PushToken\";\n\nconst expo = new Expo();\n\n/**\n * Safely extract tokens from ExpoPushMessage handling both string and array cases\n */\nfunction extractTokensFromMessage(message: ExpoPushMessage): string[] {\n return Array.isArray(message.to) ? message.to : [message.to];\n}\n\ninterface CreatePushMessagesOptions {\n tokens: string[];\n message: string;\n title: string;\n data: NotificationDataType;\n}\n\n/**\n * Create push messages from valid tokens\n */\nfunction createPushMessages({\n tokens,\n message,\n title,\n data,\n}: CreatePushMessagesOptions): {\n messages: ExpoPushMessage[];\n invalidTokens: string[];\n} {\n const messages: ExpoPushMessage[] = [];\n const invalidTokens: string[] = [];\n\n for (const token of tokens) {\n if (!Expo.isExpoPushToken(token)) {\n invalidTokens.push(token);\n continue;\n }\n\n messages.push({\n body: message,\n data: { ...data },\n sound: \"default\",\n title,\n to: token,\n });\n }\n\n return { invalidTokens, messages };\n}\n\n/**\n * Process chunk results and extract failed tokens\n */\nfunction processChunkResults(\n tickets: ExpoPushTicket[],\n chunk: ExpoPushMessage[],\n): { successCount: number; failedTokens: string[] } {\n let successCount = 0;\n const failedTokens: string[] = [];\n\n for (const [ticketIndex, ticket] of tickets.entries()) {\n if (ticket.status === \"error\") {\n const message = chunk[ticketIndex];\n if (message) {\n const tokens = extractTokensFromMessage(message);\n if (ticket.details?.error === \"DeviceNotRegistered\") {\n failedTokens.push(...tokens);\n }\n console.log(\"Push notification error\", {\n error: ticket.details?.error,\n tokens,\n });\n }\n } else {\n successCount++;\n }\n }\n\n return { failedTokens, successCount };\n}\n\n/**\n * Send a single chunk of push notifications\n */\nasync function sendChunk(\n chunk: ExpoPushMessage[],\n chunkIndex: number,\n): Promise<{ successCount: number; failedTokens: string[] }> {\n try {\n const tickets = await expo.sendPushNotificationsAsync(chunk);\n const { successCount, failedTokens } = processChunkResults(tickets, chunk);\n\n console.log(\n `Chunk ${chunkIndex + 1}: Sent ${successCount}/${chunk.length} notifications successfully`,\n );\n\n return { failedTokens, successCount };\n } catch (error) {\n console.log(\"Error sending Expo push notification chunk\", {\n chunkIndex,\n chunkSize: chunk.length,\n error: error instanceof Error ? error.message : String(error),\n });\n return { failedTokens: [], successCount: 0 };\n }\n}\n\nexport async function sendPushNotifications({\n data,\n message,\n title,\n userIds,\n}: SchemaCreateBulkNotificationInput) {\n const pushTokens = await PushTokenModel.find({ userId: { $in: userIds } });\n const expoTokens = pushTokens.map((token) => token.token);\n\n if (!data) return;\n\n const { messages, invalidTokens } = createPushMessages({\n data,\n message,\n title,\n tokens: expoTokens,\n });\n\n // Log invalid tokens\n if (invalidTokens.length > 0) {\n console.log(`Found ${invalidTokens.length} invalid push tokens`);\n }\n\n if (messages.length === 0) {\n console.log(\"No valid messages to send after filtering tokens\");\n return;\n }\n\n // Send notifications in chunks\n const chunks = expo.chunkPushNotifications(messages);\n let totalSuccessCount = 0;\n const allFailedTokens: string[] = [];\n\n for (const [chunkIndex, chunk] of chunks.entries()) {\n const { successCount, failedTokens } = await sendChunk(\n chunk,\n chunkIndex + 1,\n );\n totalSuccessCount += successCount;\n allFailedTokens.push(...failedTokens);\n }\n\n // Log final results\n console.log(\n `Sent push notification to ${totalSuccessCount}/${messages.length} tokens across ${chunks.length} chunks`,\n );\n\n if (allFailedTokens.length > 0) {\n console.log(`Found ${allFailedTokens.length} failed push tokens`);\n }\n}\n","import { EnumAdStatus } from \"@timardex/cluemart-shared\";\n\nimport { AdModel } from \"src/mongoose\";\n\n/**\n * Updates ad statuses based on start/end dates and validity\n */\nexport async function updateAdStatuses(): Promise<void> {\n const now = new Date();\n\n // invalid\n const invalidResult = await AdModel.updateMany(\n {\n $or: [\n { start: { $exists: false } },\n { end: { $exists: false } },\n { $expr: { $gt: [\"$start\", \"$end\"] } },\n ],\n status: { $ne: EnumAdStatus.PAUSED },\n },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n // expired\n const expiredResult = await AdModel.updateMany(\n { end: { $lte: now }, status: { $ne: EnumAdStatus.EXPIRED } },\n { $set: { status: EnumAdStatus.EXPIRED } },\n );\n\n // active\n const activeResult = await AdModel.updateMany(\n {\n end: { $gt: now },\n start: { $lte: now },\n status: { $ne: EnumAdStatus.ACTIVE },\n },\n { $set: { status: EnumAdStatus.ACTIVE } },\n );\n\n // paused\n const pausedResult = await AdModel.updateMany(\n { start: { $gt: now }, status: { $ne: EnumAdStatus.PAUSED } },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n console.log(\n `✅ Ad statuses updated: invalid=${invalidResult.modifiedCount}, expired=${expiredResult.modifiedCount}, active=${activeResult.modifiedCount}, paused=${pausedResult.modifiedCount}`,\n );\n}\n","import { EnumResourceType, EnumUserLicence } from \"@timardex/cluemart-shared\";\nimport mongoose from \"mongoose\";\n\nimport { SchemaVendorType, UserModel, VendorModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { removeAssociateFromResource } from \"./associate\";\n\n/**\n *\n * This function updates the vendor's features based on the user's license.\n * It checks the type of license and updates the vendor's associates and availability accordingly.\n * If the user has a Pro Vendor license, they can have multiple associates and access to all availability types.\n * If they have a Standard Vendor license, their associates are removed and availability is restricted.\n * @param userId\n * @param licenceType\n * @returns\n */\nexport async function updateVendorBasedOnUserLicense(\n userId: ObjectId,\n licenceType: EnumUserLicence,\n): Promise<void> {\n const session = await mongoose.startSession();\n\n try {\n session.startTransaction();\n\n /**\n * Fetch vendor (only required fields)\n */\n const user = await UserModel.findById(userId)\n .select(\"vendor\")\n .lean()\n .session(session);\n\n if (!user?.vendor) {\n console.warn(`[updateVendor] No vendor for userId=${userId}`);\n await session.abortTransaction();\n return;\n }\n\n const vendor = await VendorModel.findById(user.vendor)\n .lean()\n .session(session);\n\n if (!vendor) {\n console.warn(`[updateVendor] Vendor not found for id=${user.vendor}`);\n await session.abortTransaction();\n return;\n }\n\n /**\n * Build update payload\n */\n\n const vendorUpdateData: Partial<SchemaVendorType> = {};\n\n if (licenceType === EnumUserLicence.STANDARD_VENDOR) {\n vendorUpdateData.associates = [];\n\n vendorUpdateData.availability = {\n corporate: false,\n private: false,\n school: false,\n };\n\n vendorUpdateData.products = {\n active: false,\n productsList: vendor.products?.productsList ?? [],\n };\n\n vendorUpdateData.calendar = {\n active: false,\n calendarData: vendor.calendar?.calendarData ?? [],\n };\n\n vendorUpdateData.images = (vendor.images ?? []).map((img, index) => ({\n ...img,\n active: index < 6,\n }));\n } else {\n vendorUpdateData.images = (vendor.images ?? []).map((img) => ({\n ...img,\n active: true,\n }));\n }\n\n /**\n * Update vendor\n */\n await VendorModel.updateOne(\n { _id: vendor._id },\n { $set: vendorUpdateData },\n { session },\n );\n\n /**\n * Only remove associates for STANDARD licence\n */\n if (licenceType === EnumUserLicence.STANDARD_VENDOR) {\n await removeAssociateFromResource({\n resourceId: vendor._id,\n resourceOwnerId: vendor.owner.userId,\n resourceType: EnumResourceType.VENDOR,\n });\n }\n\n await session.commitTransaction();\n } catch (error) {\n await session.abortTransaction();\n console.error(\"[updateVendorBasedOnUserLicense] Failed:\", error);\n } finally {\n session.endSession();\n }\n}\n","import { EnumChatType, EnumResourceType } from \"@timardex/cluemart-shared\";\nimport mongoose from \"mongoose\";\n\nimport { ChatModel, UserModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\ninterface RemoveAssociateFromResourceParams {\n resourceId: string | ObjectId;\n resourceOwnerId: string | ObjectId;\n resourceType: EnumResourceType;\n}\n\n/**\n * Removes all associates linked to a specific resource\n * and deactivates corresponding chat participants.\n *\n * Flow:\n * 1. Find all associates (emails) BEFORE removing them\n * 2. Remove associates from User documents\n * 3. Deactivate matching participants in chats\n *\n * Uses a MongoDB transaction to ensure consistency.\n */\nexport async function removeAssociateFromResource({\n resourceId,\n resourceOwnerId,\n resourceType,\n}: RemoveAssociateFromResourceParams): Promise<void> {\n const normalizedResourceId = resourceId.toString();\n const normalizedOwnerId =\n typeof resourceOwnerId === \"string\"\n ? new mongoose.Types.ObjectId(resourceOwnerId)\n : resourceOwnerId;\n\n const session = await mongoose.startSession();\n\n try {\n session.startTransaction();\n\n /**\n * STEP 1: Fetch all users that have matching associates\n * We do this BEFORE removal because MongoDB does not return\n * removed elements from `$pull`\n */\n const usersWithAssociates = await UserModel.find(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n associates: 1, // Only fetch associates field for efficiency\n },\n )\n .lean()\n .session(session);\n\n /**\n * Extract emails of associates that match the resource\n */\n const associateEmails = usersWithAssociates.flatMap((user) =>\n (user.associates ?? [])\n .filter(\n (assoc) =>\n assoc.resourceId === normalizedResourceId &&\n assoc.resourceType === resourceType,\n )\n .map((assoc) => assoc.email),\n );\n\n /**\n * Early exit: no associates found → nothing to update\n */\n if (associateEmails.length === 0) {\n await session.commitTransaction();\n return;\n }\n\n /**\n * STEP 2: Remove associates from all users\n */\n await UserModel.updateMany(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n $pull: {\n associates: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n { session },\n );\n\n /**\n * STEP 3: Deactivate matching participants in chats\n *\n * Conditions:\n * - Only RELATION chats\n * - Chat must be active and not deleted\n * - Must include the resource owner as a participant\n * - Only deactivate participants:\n * - with matching email\n * - where isAssociate === true\n */\n await ChatModel.updateMany(\n {\n active: true,\n chatType: EnumChatType.RELATION,\n deletedAt: null,\n participants: {\n $elemMatch: {\n userId: normalizedOwnerId,\n },\n },\n },\n {\n $set: {\n \"participants.$[assoc].active\": false,\n },\n },\n {\n arrayFilters: [\n {\n \"assoc.isAssociate\": true,\n \"assoc.userEmail\": { $in: associateEmails },\n },\n ],\n session,\n },\n );\n\n /**\n * Commit transaction if everything succeeded\n */\n await session.commitTransaction();\n } catch (error) {\n /**\n * Rollback all changes if anything fails\n */\n await session.abortTransaction();\n\n console.error(\n `[removeAssociateFromResource] Failed for resourceId=${normalizedResourceId}, resourceType=${resourceType}`,\n error,\n );\n\n throw error; // Re-throw so caller can handle it\n } finally {\n /**\n * Always end the session\n */\n session.endSession();\n }\n}\n","import mongoose from \"mongoose\";\n\n/**\n * Recursively converts all ObjectId fields to strings in an object\n * This is needed because GraphQL expects string IDs, not ObjectIds\n */\nexport function convertObjectIdsToStrings(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (obj instanceof mongoose.Types.ObjectId) {\n return obj.toString();\n }\n\n if (Array.isArray(obj)) {\n return obj.map(convertObjectIdsToStrings);\n }\n\n if (typeof obj === \"object\") {\n const converted: any = {};\n for (const [key, value] of Object.entries(obj)) {\n converted[key] = convertObjectIdsToStrings(value);\n }\n return converted;\n }\n\n return obj;\n}\n","import { EventModel, GoogleImportedMarketModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { convertObjectIdsToStrings } from \"./objectIdToString\";\n\ntype EventOrMarket = { _id: ObjectId | string; name: string } | null;\n\n/**\n * This function attempts to find an Event or a Google Imported Market by the given resource ID.\n * It first normalizes the resource ID to a string format, then performs parallel queries to both collections.\n * If an Event is found, it returns that; otherwise, it checks for a Google Imported Market and returns it if found.\n * If neither is found, it returns null.\n * @param resourceId - The ID of the resource to find, which can be an ObjectId, string, null, or undefined.\n * @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.\n */\n\nexport async function findEventOrImportedMarketById(\n resourceId: ObjectId | string | null | undefined,\n): Promise<EventOrMarket> {\n if (!resourceId) {\n return null;\n }\n\n const normalizedId = convertObjectIdsToStrings(resourceId) as string;\n\n const [eventDoc, googleImportedDoc] = await Promise.all([\n EventModel.findById(normalizedId).select(\"_id name\").lean().exec(),\n GoogleImportedMarketModel.findById(normalizedId)\n .select(\"_id name\")\n .lean()\n .exec(),\n ]);\n\n return eventDoc ?? googleImportedDoc;\n}\n"],"mappings":"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","names":["mongoose","mongoose","mongoose","mongoose","mongoose"]}
|
package/dist/types/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import { EnumUserRole } from \"@timardex/cluemart-shared\";\nimport { NotificationCount } from \"@timardex/cluemart-shared/types\";\nimport express from \"express\";\nimport mongoose from \"mongoose\";\n\nimport { SchemaChatType } from \"../mongoose/chat/Chat\";\nimport { SchemaNotificationType } from \"../mongoose/Notification\";\n\n// chnage to export type ObjectId = mongoose.Types.ObjectId;\n// chnage in server when setting decideGameType\nexport type ObjectId = mongoose.
|
|
1
|
+
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import { EnumUserRole } from \"@timardex/cluemart-shared\";\nimport { NotificationCount } from \"@timardex/cluemart-shared/types\";\nimport express from \"express\";\nimport mongoose from \"mongoose\";\n\nimport { SchemaChatType } from \"../mongoose/chat/Chat\";\nimport { SchemaNotificationType } from \"../mongoose/Notification\";\n\n// chnage to export type ObjectId = mongoose.Types.ObjectId;\n// chnage in server when setting decideGameType\nexport type ObjectId = mongoose.Types.ObjectId;\n\nexport enum EnumPubSubEvents {\n GET_CHAT_MESSAGE = \"GET_CHAT_MESSAGE\",\n GET_NOTIFICATIONS = \"GET_NOTIFICATIONS\",\n GET_NOTIFICATIONS_COUNT = \"GET_NOTIFICATIONS_COUNT\",\n USER_TYPING = \"USER_TYPING\",\n}\n\nexport interface AuthUser {\n email: string;\n role: EnumUserRole;\n userId: ObjectId;\n}\n\nexport interface SubscriptionPayload {\n getChatMessage?: SchemaChatType;\n userTyping?: SchemaChatType; // NOT USED\n getNotifications?: SchemaNotificationType[];\n // Used only for filtering; not part of the GraphQL schema output\n getNotificationsUserId?: ObjectId;\n getNotificationsCount?: NotificationCount & { userId: ObjectId };\n}\n\nexport interface GraphQLContext {\n appVersion: string | null;\n user: AuthUser | null;\n pubsub: {\n publish: (\n eventName: EnumPubSubEvents,\n payload: SubscriptionPayload,\n ) => void;\n subscribe: (eventName: EnumPubSubEvents) => AsyncIterable<any>;\n };\n request: express.Request;\n response: express.Response;\n}\n\nexport { mongoose, express };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,gCAAAA;AAAA,EAAA,gCAAAC;AAAA;AAAA;AAEA,qBAAoB;AACpB,sBAAqB;AASd,IAAK,mBAAL,kBAAKC,sBAAL;AACL,EAAAA,kBAAA,sBAAmB;AACnB,EAAAA,kBAAA,uBAAoB;AACpB,EAAAA,kBAAA,6BAA0B;AAC1B,EAAAA,kBAAA,iBAAc;AAJJ,SAAAA;AAAA,GAAA;","names":["express","mongoose","EnumPubSubEvents"]}
|
package/dist/types/index.d.mts
CHANGED
|
@@ -2,4 +2,4 @@ import '@timardex/cluemart-shared';
|
|
|
2
2
|
import '@timardex/cluemart-shared/types';
|
|
3
3
|
export { default as express } from 'express';
|
|
4
4
|
export { default as mongoose } from 'mongoose';
|
|
5
|
-
export { A as AuthUser, E as EnumPubSubEvents, G as GraphQLContext, O as ObjectId, h as SubscriptionPayload } from '../Chat-
|
|
5
|
+
export { A as AuthUser, E as EnumPubSubEvents, G as GraphQLContext, O as ObjectId, h as SubscriptionPayload } from '../Chat-Ctmtatmi.mjs';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import '@timardex/cluemart-shared';
|
|
|
2
2
|
import '@timardex/cluemart-shared/types';
|
|
3
3
|
export { default as express } from 'express';
|
|
4
4
|
export { default as mongoose } from 'mongoose';
|
|
5
|
-
export { A as AuthUser, E as EnumPubSubEvents, G as GraphQLContext, O as ObjectId, h as SubscriptionPayload } from '../Chat-
|
|
5
|
+
export { A as AuthUser, E as EnumPubSubEvents, G as GraphQLContext, O as ObjectId, h as SubscriptionPayload } from '../Chat-Ctmtatmi.js';
|
package/dist/types/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import { EnumUserRole } from \"@timardex/cluemart-shared\";\nimport { NotificationCount } from \"@timardex/cluemart-shared/types\";\nimport express from \"express\";\nimport mongoose from \"mongoose\";\n\nimport { SchemaChatType } from \"../mongoose/chat/Chat\";\nimport { SchemaNotificationType } from \"../mongoose/Notification\";\n\n// chnage to export type ObjectId = mongoose.Types.ObjectId;\n// chnage in server when setting decideGameType\nexport type ObjectId = mongoose.
|
|
1
|
+
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import { EnumUserRole } from \"@timardex/cluemart-shared\";\nimport { NotificationCount } from \"@timardex/cluemart-shared/types\";\nimport express from \"express\";\nimport mongoose from \"mongoose\";\n\nimport { SchemaChatType } from \"../mongoose/chat/Chat\";\nimport { SchemaNotificationType } from \"../mongoose/Notification\";\n\n// chnage to export type ObjectId = mongoose.Types.ObjectId;\n// chnage in server when setting decideGameType\nexport type ObjectId = mongoose.Types.ObjectId;\n\nexport enum EnumPubSubEvents {\n GET_CHAT_MESSAGE = \"GET_CHAT_MESSAGE\",\n GET_NOTIFICATIONS = \"GET_NOTIFICATIONS\",\n GET_NOTIFICATIONS_COUNT = \"GET_NOTIFICATIONS_COUNT\",\n USER_TYPING = \"USER_TYPING\",\n}\n\nexport interface AuthUser {\n email: string;\n role: EnumUserRole;\n userId: ObjectId;\n}\n\nexport interface SubscriptionPayload {\n getChatMessage?: SchemaChatType;\n userTyping?: SchemaChatType; // NOT USED\n getNotifications?: SchemaNotificationType[];\n // Used only for filtering; not part of the GraphQL schema output\n getNotificationsUserId?: ObjectId;\n getNotificationsCount?: NotificationCount & { userId: ObjectId };\n}\n\nexport interface GraphQLContext {\n appVersion: string | null;\n user: AuthUser | null;\n pubsub: {\n publish: (\n eventName: EnumPubSubEvents,\n payload: SubscriptionPayload,\n ) => void;\n subscribe: (eventName: EnumPubSubEvents) => AsyncIterable<any>;\n };\n request: express.Request;\n response: express.Response;\n}\n\nexport { mongoose, express };\n"],"mappings":";;;AAEA,OAAO,aAAa;AACpB,OAAO,cAAc;AASd,IAAK,mBAAL,kBAAKA,sBAAL;AACL,EAAAA,kBAAA,sBAAmB;AACnB,EAAAA,kBAAA,uBAAoB;AACpB,EAAAA,kBAAA,6BAA0B;AAC1B,EAAAA,kBAAA,iBAAc;AAJJ,SAAAA;AAAA,GAAA;","names":["EnumPubSubEvents"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timardex/cluemart-server-shared",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.150",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"author": "Csaba Timár",
|
|
42
42
|
"license": "ISC",
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@timardex/cluemart-shared": "^1.5.
|
|
44
|
+
"@timardex/cluemart-shared": "^1.5.554",
|
|
45
45
|
"@types/express": "^5.0.5",
|
|
46
46
|
"@types/node": "^22.13.4",
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^8.20.0",
|