abmp-npm 1.1.97 → 1.1.99

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.
@@ -11,7 +11,7 @@ const elevatedCreateContact = auth.elevate(contacts.createContact);
11
11
  * @param {boolean} allowDuplicates - Allow duplicates if contact with same email already exists, will be true only when handling existing members, after that should be removed
12
12
  * @returns {Promise<Object>} - Contact data
13
13
  */
14
- async function createContact(contactData, allowDuplicates = false) {
14
+ async function createSiteContact(contactData, allowDuplicates = false) {
15
15
  if (!contactData || !(contactData.contactFormEmail || contactData.email)) {
16
16
  throw new Error('Contact data is required');
17
17
  }
@@ -22,10 +22,10 @@ async function createContact(contactData, allowDuplicates = false) {
22
22
  first: contactData.firstName,
23
23
  last: contactData.lastName,
24
24
  },
25
- emails: [
26
- { items: [{ email: contactData.contactFormEmail || contactData.email, primary: true }] },
27
- ],
28
- phones: [{ items: phones.map(phone => ({ phone })) }],
25
+ emails: {
26
+ items: [{ email: contactData.contactFormEmail || contactData.email, primary: true }],
27
+ },
28
+ phones: { items: phones.map(phone => ({ phone })) },
29
29
  };
30
30
  const createContactResponse = await elevatedCreateContact(contactInfo, { allowDuplicates });
31
31
  return createContactResponse.contact._id;
@@ -157,5 +157,5 @@ const updateMemberContactInfo = async (data, existingMemberData) => {
157
157
 
158
158
  module.exports = {
159
159
  updateMemberContactInfo,
160
- createContact,
160
+ createSiteContact,
161
161
  };
@@ -1,3 +1,5 @@
1
+ const { COLLECTIONS } = require('../public/consts');
2
+
1
3
  const { ensureUniqueUrlsInBatch } = require('./daily-pull/bulk-process-methods');
2
4
  const { wixData } = require('./elevated-modules');
3
5
  const { bulkSaveMembers } = require('./members-data-methods');
@@ -15,4 +17,14 @@ async function deduplicateURls(collectionName, duplicateUrlsList) {
15
17
  return await bulkSaveMembers(membersWithUniqueUrls, collectionName);
16
18
  }
17
19
 
18
- module.exports = { deduplicateURls };
20
+ async function copyContactIdToWixMemberId() {
21
+ const query = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('contactId');
22
+ const members = await queryAllItems(query);
23
+ const updatedMembers = members.map(member => ({
24
+ ...member,
25
+ wixMemberId: member.contactId,
26
+ }));
27
+ return await bulkSaveMembers(updatedMembers, COLLECTIONS.MEMBERS_DATA);
28
+ }
29
+
30
+ module.exports = { deduplicateURls, copyContactIdToWixMemberId };
@@ -5,7 +5,7 @@ const { decode } = require('jwt-js-decode');
5
5
  const { CONFIG_KEYS, SSO_TOKEN_AUTH_API_URL } = require('../consts');
6
6
  const { MEMBER_ACTIONS } = require('../daily-pull/consts');
7
7
  const { getCurrentMember } = require('../members-area-methods');
8
- const { getMemberByContactId, prepareMemberForSSOLogin } = require('../members-data-methods');
8
+ const { getCMSMemberByWixMemberId, prepareMemberForSSOLogin } = require('../members-data-methods');
9
9
  const {
10
10
  formatDateToMonthYear,
11
11
  getAddressDisplayOptions,
@@ -37,12 +37,12 @@ async function validateMemberToken(memberIdInput) {
37
37
  }
38
38
 
39
39
  const [dbMember, siteConfigs] = await Promise.all([
40
- getMemberByContactId(member._id),
40
+ getCMSMemberByWixMemberId(member._id),
41
41
  getSiteConfigs(),
42
42
  ]);
43
43
  const siteAssociation = siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION];
44
44
  const membersExternalPortalUrl = siteConfigs[CONFIG_KEYS.MEMBERS_EXTERNAL_PORTAL_URL];
45
- console.log('dbMember by contact id is:', dbMember);
45
+ console.log('dbMember by wix member id is:', dbMember);
46
46
  console.log('member._id', member._id);
47
47
 
48
48
  if (!dbMember?._id) {
@@ -1,7 +1,8 @@
1
1
  const { COLLECTIONS } = require('../public/consts');
2
+ const { isWixHostedImage } = require('../public/Utils/sharedUtils');
2
3
 
3
4
  const { MEMBERSHIPS_TYPES } = require('./consts');
4
- const { updateMemberContactInfo, createContact } = require('./contacts-methods');
5
+ const { updateMemberContactInfo, createSiteContact } = require('./contacts-methods');
5
6
  const { MEMBER_ACTIONS } = require('./daily-pull/consts');
6
7
  const { wixData } = require('./elevated-modules');
7
8
  const { createSiteMember, getCurrentMember } = require('./members-area-methods');
@@ -42,14 +43,16 @@ async function createContactAndMemberIfNew(memberData) {
42
43
  phones: memberData.phones,
43
44
  contactFormEmail: memberData.contactFormEmail || memberData.email,
44
45
  };
45
- const [wixMemberId, wixContactId] = await Promise.all([
46
- createSiteMember(toCreateMemberData),
47
- createContact(toCreateMemberData),
46
+ const needsWixMember = !memberData.wixMemberId;
47
+ const needsWixContact = !memberData.wixContactId;
48
+ const [newWixMemberId, newWixContactId] = await Promise.all([
49
+ needsWixMember ? createSiteMember(toCreateMemberData) : Promise.resolve(null),
50
+ needsWixContact ? createSiteContact(toCreateMemberData) : Promise.resolve(null),
48
51
  ]);
49
52
  let memberDataWithContactId = {
50
53
  ...memberData,
51
- wixMemberId,
52
- wixContactId,
54
+ wixMemberId: newWixMemberId || memberData.wixMemberId,
55
+ wixContactId: newWixContactId || memberData.wixContactId,
53
56
  };
54
57
  const updatedResult = await updateMember(memberDataWithContactId);
55
58
  memberDataWithContactId = {
@@ -173,26 +176,26 @@ async function getMemberBySlug({
173
176
  }
174
177
  }
175
178
 
176
- async function getMemberByContactId(contactId) {
177
- if (!contactId) {
178
- throw new Error('Contact ID is required');
179
+ async function getCMSMemberByWixMemberId(wixMemberId) {
180
+ if (!wixMemberId) {
181
+ throw new Error('Wix Member ID is required');
179
182
  }
180
183
  try {
181
184
  const members = await wixData
182
185
  .query(COLLECTIONS.MEMBERS_DATA)
183
- .eq('contactId', contactId)
186
+ .eq('wixMemberId', wixMemberId)
184
187
  .limit(2)
185
188
  .find()
186
189
  .then(res => res.items);
187
190
  if (members.length > 1) {
188
191
  throw new Error(
189
- `[getMemberByContactId] Multiple members found with contactId ${contactId} membersIds are : [${members.map(member => member.memberId).join(', ')}]`
192
+ `[getCMSMemberByWixMemberId] Multiple members found with wixMemberId ${wixMemberId} membersIds are : [${members.map(member => member.memberId).join(', ')}]`
190
193
  );
191
194
  }
192
195
  return members[0] || null;
193
196
  } catch (error) {
194
197
  throw new Error(
195
- `[getMemberByContactId] Failed to retrieve member by contactId ${contactId} data: ${error.message}`
198
+ `[getCMSMemberByWixMemberId] Failed to retrieve member by wixMemberId ${wixMemberId} data: ${error.message}`
196
199
  );
197
200
  }
198
201
  }
@@ -328,9 +331,9 @@ async function getAllMembersWithExternalImages() {
328
331
 
329
332
  const allItems = await queryAllItems(membersQuery);
330
333
 
331
- // Filter for external images (not starting with 'wix:')
334
+ // Filter for external images (not 'wix hosted images')
332
335
  const membersWithExternalImages = allItems.filter(
333
- member => member.profileImage && !member.profileImage.startsWith('wix:')
336
+ member => member.profileImage && !isWixHostedImage(member.profileImage)
334
337
  );
335
338
 
336
339
  return membersWithExternalImages;
@@ -454,13 +457,13 @@ const getQAUsers = async () => {
454
457
  /**
455
458
  * Ensures member has a contact - creates one if missing
456
459
  * @param {Object} memberData - Member data from DB
457
- * @returns {Promise<Object>} - Member data with contactId
460
+ * @returns {Promise<Object>} - Member data with contact and member IDs
458
461
  */
459
- async function ensureMemberHasContact(memberData) {
462
+ async function ensureWixMemberAndContactExist(memberData) {
460
463
  if (!memberData) {
461
464
  throw new Error('Member data is required');
462
465
  }
463
- if (!memberData.contactId) {
466
+ if (!memberData.wixContactId || !memberData.wixMemberId) {
464
467
  const memberDataWithContactId = await createContactAndMemberIfNew(memberData);
465
468
  return memberDataWithContactId;
466
469
  }
@@ -478,7 +481,7 @@ async function prepareMemberForSSOLogin(data) {
478
481
  throw new Error(`Member data not found for memberId ${memberId}`);
479
482
  }
480
483
  console.log('memberData', memberData);
481
- return await ensureMemberHasContact(memberData);
484
+ return await ensureWixMemberAndContactExist(memberData);
482
485
  } catch (error) {
483
486
  console.error('Error in prepareMemberForSSOLogin', error.message);
484
487
  throw error;
@@ -495,7 +498,7 @@ async function prepareMemberForQALogin(email) {
495
498
  throw new Error(`Member data not found for email ${email}`);
496
499
  }
497
500
  console.log('memberData', memberData);
498
- return await ensureMemberHasContact(memberData);
501
+ return await ensureWixMemberAndContactExist(memberData);
499
502
  } catch (error) {
500
503
  console.error('Error in prepareMemberForQALogin', error.message);
501
504
  throw error;
@@ -517,11 +520,11 @@ async function trackButtonClick({ pageName, buttonName }) {
517
520
  return null;
518
521
  }
519
522
 
520
- const dbMember = await getMemberByContactId(wixMember._id);
523
+ const dbMember = await getCMSMemberByWixMemberId(wixMember._id);
521
524
 
522
525
  if (!dbMember) {
523
526
  console.warn(
524
- `[trackButtonClick]: Member not found in MembersDataLatest for contactId: ${wixMember._id}`
527
+ `[trackButtonClick]: Member not found in MembersDataLatest for wixMemberId: ${wixMember._id}`
525
528
  );
526
529
  return null;
527
530
  }
@@ -547,14 +550,20 @@ async function trackButtonClick({ pageName, buttonName }) {
547
550
  }
548
551
  }
549
552
 
553
+ async function getAllMembersWithWixMemberId() {
554
+ const membersQuery = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('wixMemberId');
555
+ return await queryAllItems(membersQuery);
556
+ }
557
+
550
558
  module.exports = {
551
559
  findMemberByWixDataId,
552
560
  createContactAndMemberIfNew,
561
+ getAllMembersWithWixMemberId,
553
562
  saveRegistrationData,
554
563
  bulkSaveMembers,
555
564
  findMemberById,
556
565
  getMemberBySlug,
557
- getMemberByContactId,
566
+ getCMSMemberByWixMemberId,
558
567
  getAllEmptyAboutYouMembers,
559
568
  updateMember,
560
569
  getAllMembersWithExternalImages,
@@ -1,4 +1,5 @@
1
1
  const { PAGES_PATHS } = require('../../public/consts');
2
+ const { isWixHostedImage } = require('../../public/Utils/sharedUtils');
2
3
  //const { fetchAllItemsInParallel } = require('../cms-data-methods'); unused at host site
3
4
  const { CONFIG_KEYS } = require('../consts');
4
5
  const { getSiteConfigs } = require('../utils');
@@ -27,7 +28,11 @@ const createRoutersHandlers = wixRouterMethods => {
27
28
  const defaultProfileImage = siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_IMAGE];
28
29
  const profileData = await getMemberProfileData(slug, siteAssociation);
29
30
  if (profileData && profileData.showWixUrl) {
30
- const ogImage = profileData.profileImage || profileData.logoImage || siteLogoUrl;
31
+ const profileImage =
32
+ profileData.profileImage?.trim() && isWixHostedImage(profileData.profileImage)
33
+ ? profileData.profileImage
34
+ : defaultProfileImage;
35
+ const ogImage = profileImage || profileData.logoImage || siteLogoUrl;
31
36
  const seoTitle = generateSEOTitle({
32
37
  fullName: profileData.fullName,
33
38
  areasOfPractices: profileData.areasOfPractices,
@@ -16,6 +16,8 @@ const TASKS_NAMES = {
16
16
  migrateUrlsChunk: 'migrateUrlsChunk',
17
17
  scheduleGenerateMissingUrls: 'scheduleGenerateMissingUrls',
18
18
  generateUrlsChunk: 'generateUrlsChunk',
19
+ scheduleCreateContactsFromMembers: 'scheduleCreateContactsFromMembers',
20
+ createContactsFromMembers: 'createContactsFromMembers',
19
21
  };
20
22
 
21
23
  module.exports = {
@@ -16,6 +16,8 @@ const {
16
16
  migrateContactFormEmails,
17
17
  scheduleEmailSync,
18
18
  syncMemberLoginEmails,
19
+ scheduleCreateContactsFromMembers,
20
+ createContactsFromMembers,
19
21
  } = require('./tasks-process-methods');
20
22
  const {
21
23
  scheduleMigrateExistingUrls,
@@ -153,6 +155,20 @@ const TASKS = {
153
155
  shouldSkipCheck: () => false,
154
156
  estimatedDurationSec: 80,
155
157
  },
158
+ [TASKS_NAMES.scheduleCreateContactsFromMembers]: {
159
+ name: TASKS_NAMES.scheduleCreateContactsFromMembers,
160
+ getIdentifier: () => 'SHOULD_NEVER_SKIP',
161
+ process: scheduleCreateContactsFromMembers,
162
+ shouldSkipCheck: () => false,
163
+ estimatedDurationSec: 80,
164
+ },
165
+ [TASKS_NAMES.createContactsFromMembers]: {
166
+ name: TASKS_NAMES.createContactsFromMembers,
167
+ getIdentifier: task => task.data,
168
+ process: createContactsFromMembers,
169
+ shouldSkipCheck: () => false,
170
+ estimatedDurationSec: 80,
171
+ },
156
172
  };
157
173
 
158
174
  module.exports = { TASKS };
@@ -5,6 +5,7 @@ const aws4 = require('aws4');
5
5
  const axios = require('axios');
6
6
 
7
7
  const { PAGES_PATHS } = require('../../public/consts');
8
+ const { isWixHostedImage } = require('../../public/Utils/sharedUtils');
8
9
  const { findMemberByWixDataId, updateMember } = require('../members-data-methods');
9
10
  const { getSecret, getSiteBaseUrl, encodeXml, formatDateOnly } = require('../utils');
10
11
 
@@ -140,11 +141,7 @@ async function updateMemberProfileImage(memberId) {
140
141
  const member = await findMemberByWixDataId(memberId);
141
142
  const trimmedProfileImage = member.profileImage.trim();
142
143
  // Check if member has an external profile image URL
143
- if (
144
- !trimmedProfileImage ||
145
- trimmedProfileImage.startsWith('wix:') ||
146
- trimmedProfileImage.startsWith('https://static.wixstatic.com')
147
- ) {
144
+ if (!trimmedProfileImage || isWixHostedImage(trimmedProfileImage)) {
148
145
  console.log(`Member ${memberId} already has Wix-hosted image or no image`);
149
146
  return { success: true, message: 'No update needed' };
150
147
  }
@@ -13,6 +13,8 @@ const {
13
13
  bulkSaveMembers,
14
14
  getAllUpdatedLoginEmails,
15
15
  getMembersByIds,
16
+ createContactAndMemberIfNew,
17
+ getAllMembersWithWixMemberId,
16
18
  } = require('../members-data-methods');
17
19
  const {
18
20
  getCompleteStateList,
@@ -530,6 +532,46 @@ const syncMemberLoginEmails = async data => {
530
532
  throw new Error(errorMessage);
531
533
  }
532
534
  };
535
+ /**
536
+ * Schedules tasks to create contacts from members
537
+ * dev-only task, run only once by the developers
538
+ */
539
+ const scheduleCreateContactsFromMembers = async () => {
540
+ const members = await getAllMembersWithWixMemberId();
541
+ console.log(
542
+ `Starting to schedule create contacts from members tasks for ${members.length} members in chunks of 500 members`
543
+ );
544
+ const membersChunks = chunkArray(members, 500);
545
+ for (let chunkIndex = 0; chunkIndex < membersChunks.length; chunkIndex++) {
546
+ const chunk = membersChunks[chunkIndex];
547
+ const toScheduleTask = {
548
+ name: TASKS_NAMES.createContactsFromMembers,
549
+ data: { chunk, chunkIndex },
550
+ };
551
+ await taskManager().schedule(toScheduleTask);
552
+ console.log(`Scheduled task for chunk ${chunkIndex} with ${chunk.length} members`);
553
+ }
554
+ console.log(`Successfully scheduled ${membersChunks.length} tasks for ${members.length} members`);
555
+ };
556
+
557
+ /**
558
+ * Creates contacts from members
559
+ * dev-only task, run only once by the developers
560
+ */
561
+ const createContactsFromMembers = async data => {
562
+ const { chunk, chunkIndex } = data;
563
+ console.log(`Creating contacts from ${chunk.length} members in chunk ${chunkIndex}`);
564
+ const createPromises = chunk.map(member => createContactAndMemberIfNew(member));
565
+ const createResults = await Promise.all(createPromises);
566
+ console.log(
567
+ `Created ${createResults.length} contacts from ${chunk.length} members in chunk ${chunkIndex}`
568
+ );
569
+ const saveResult = await bulkSaveMembers(createResults);
570
+ console.log(
571
+ `Successfully saved ${saveResult.totalSaved} contacts from ${chunk.length} members in chunk ${chunkIndex}`
572
+ );
573
+ return saveResult;
574
+ };
533
575
 
534
576
  module.exports = {
535
577
  scheduleTaskForEmptyAboutYouMembers,
@@ -542,4 +584,6 @@ module.exports = {
542
584
  migrateContactFormEmails,
543
585
  scheduleEmailSync,
544
586
  syncMemberLoginEmails,
587
+ scheduleCreateContactsFromMembers, // run only once by the developers
588
+ createContactsFromMembers,
545
589
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmp-npm",
3
- "version": "1.1.97",
3
+ "version": "1.1.99",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "check-cycles": "madge --circular .",
package/pages/Home.js CHANGED
@@ -9,6 +9,7 @@ const {
9
9
  getMainAddress,
10
10
  formatPracticeAreasForDisplay,
11
11
  checkAddressIsVisible,
12
+ isWixHostedImage,
12
13
  } = require('../public/Utils/sharedUtils.js');
13
14
 
14
15
  let filter = JSON.parse(JSON.stringify(DEFAULT_FILTER));
@@ -187,7 +188,7 @@ const homePageOnReady = async ({
187
188
  : [];
188
189
 
189
190
  // 2) Profile image
190
- if (itemData.profileImage) {
191
+ if (itemData.profileImage?.trim() && isWixHostedImage(itemData.profileImage)) {
191
192
  $item('#profileImage').src = itemData.profileImage;
192
193
  }
193
194
 
package/pages/Profile.js CHANGED
@@ -2,7 +2,11 @@ const { location: wixLocation } = require('@wix/site-location');
2
2
  const { window: wixWindow } = require('@wix/site-window');
3
3
 
4
4
  const { LIGHTBOX_NAMES } = require('../public/consts');
5
- const { generateId, formatPracticeAreasForDisplay } = require('../public/Utils/sharedUtils');
5
+ const {
6
+ generateId,
7
+ formatPracticeAreasForDisplay,
8
+ isWixHostedImage,
9
+ } = require('../public/Utils/sharedUtils');
6
10
 
7
11
  const TESTIMONIALS_PER_PAGE_CONFIG = {
8
12
  DESKTOP: 4,
@@ -117,7 +121,7 @@ async function profileOnReady({ $w: _$w }) {
117
121
  _$w('#logoImage').delete();
118
122
  }
119
123
 
120
- if (profileData.profileImage) {
124
+ if (profileData.profileImage && isWixHostedImage(profileData.profileImage)) {
121
125
  _$w('#profileImage').src = profileData.profileImage;
122
126
  } else {
123
127
  _$w('#profileImage').src = profileData.defaultProfileImage;
@@ -9,7 +9,7 @@ const {
9
9
  LIGHTBOX_NAMES,
10
10
  } = require('../public/consts');
11
11
  const { handleOnCustomValidation, isNotValidUrl } = require('../public/Utils/personalDetailsUtils');
12
- const { generateId } = require('../public/Utils/sharedUtils');
12
+ const { generateId, isWixHostedImage } = require('../public/Utils/sharedUtils');
13
13
 
14
14
  const MAX_PHONES_COUNT = 10;
15
15
  const MAX_ADDRESSES_COUNT = 10;
@@ -793,8 +793,14 @@ async function personalDetailsOnReady({
793
793
  : null
794
794
  : itemMemberObj[key];
795
795
 
796
- if (imageValue) {
797
- _$w(imageSelector).src = imageValue;
796
+ if (imageValue && imageValue?.trim()) {
797
+ // Only set profile image if it's Wix-hosted; other images will always be wix url
798
+ const isProfileImage = imageSelector === '#profileImage';
799
+ const shouldSetImage = !isProfileImage || isWixHostedImage(imageValue);
800
+
801
+ if (shouldSetImage) {
802
+ _$w(imageSelector).src = imageValue;
803
+ }
798
804
  _$w(nameSelector).text = formatFileName(extractFileName(imageValue));
799
805
  _$w(containerSelector).expand();
800
806
  uploadedImages[key === 'bannerImages' ? 'bannerImage' : key] = imageValue;
@@ -158,6 +158,13 @@ function generateId() {
158
158
  return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
159
159
  }
160
160
 
161
+ function isWixHostedImage(imageUrl) {
162
+ return (
163
+ imageUrl?.trim() &&
164
+ (imageUrl?.startsWith('wix:') || imageUrl?.startsWith('https://static.wixstatic.com'))
165
+ );
166
+ }
167
+
161
168
  module.exports = {
162
169
  checkAddressIsVisible,
163
170
  formatPracticeAreasForDisplay,
@@ -169,4 +176,5 @@ module.exports = {
169
176
  toRadians,
170
177
  generateId,
171
178
  formatAddress,
179
+ isWixHostedImage,
172
180
  };