abmp-npm 1.1.52 → 1.1.53
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/backend/cms-data-methods.js +26 -0
- package/backend/consts.js +1 -0
- package/backend/contacts-methods.js +128 -0
- package/backend/index.js +2 -0
- package/backend/members-area-methods.js +6 -0
- package/backend/members-data-methods.js +91 -5
- package/backend/sso-methods.js +88 -0
- package/backend/utils.js +67 -0
- package/eslint.config.js +1 -1
- package/package.json +2 -1
- package/pages/Profile.js +350 -0
- package/pages/index.js +2 -0
- package/pages/personalDetails.js +2023 -0
- package/public/Utils/personalDetailsUtils.js +25 -0
- package/public/Utils/sharedUtils.js +9 -0
- package/public/consts.js +19 -0
|
@@ -207,7 +207,33 @@ async function fetchAllItemsInParallel(query) {
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Get all interests from the database
|
|
212
|
+
* @returns {Promise<Array<string>>} Array of interest titles sorted alphabetically
|
|
213
|
+
*/
|
|
214
|
+
async function getInterestAll() {
|
|
215
|
+
try {
|
|
216
|
+
let res = await wixData.query(COLLECTIONS.INTERESTS).limit(1000).find();
|
|
217
|
+
|
|
218
|
+
let interests = res.items.map(x => x.title);
|
|
219
|
+
|
|
220
|
+
while (res.hasNext()) {
|
|
221
|
+
res = await res.next();
|
|
222
|
+
interests.push(...res.items.map(x => x.title));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Sort the interests alphabetically (case-insensitive)
|
|
226
|
+
interests = interests.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
227
|
+
|
|
228
|
+
return interests;
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.error('Error in getInterestAll:', e);
|
|
231
|
+
throw e;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
210
235
|
module.exports = {
|
|
211
236
|
buildMembersSearchQuery,
|
|
212
237
|
fetchAllItemsInParallel,
|
|
238
|
+
getInterestAll,
|
|
213
239
|
};
|
package/backend/consts.js
CHANGED
|
@@ -12,6 +12,7 @@ const CONFIG_KEYS = {
|
|
|
12
12
|
INTERESTS_API_URL: 'INTERESTS_API_URL',
|
|
13
13
|
SITE_LOGO_URL: 'SITE_LOGO_URL',
|
|
14
14
|
MEMBERS_EXTERNAL_PORTAL_URL: 'MEMBERS_EXTERNAL_PORTAL_URL',
|
|
15
|
+
DEFAULT_PROFILE_IMAGE: 'DEFAULT_PROFILE_IMAGE',
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
const MAX__MEMBERS_SEARCH_RESULTS = 120;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const { contacts } = require('@wix/crm');
|
|
2
|
+
const { auth } = require('@wix/essentials');
|
|
3
|
+
|
|
4
|
+
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
5
|
+
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generic contact update helper function
|
|
9
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
10
|
+
* @param {function} updateInfoCallback - Function that returns the updated info object
|
|
11
|
+
* @param {string} operationName - Name of the operation for logging
|
|
12
|
+
*/
|
|
13
|
+
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
14
|
+
if (!contactId) {
|
|
15
|
+
throw new Error('Contact ID is required');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const contact = await elevatedGetContact(contactId);
|
|
20
|
+
const currentInfo = contact.info;
|
|
21
|
+
const updatedInfo = updateInfoCallback(currentInfo);
|
|
22
|
+
|
|
23
|
+
await elevatedUpdateContact(contactId, { info: updatedInfo }, contact.revision);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error(`Error in ${operationName}:`, error);
|
|
26
|
+
throw new Error(`Failed to ${operationName}: ${error.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Updates contact email in Wix CRM
|
|
32
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
33
|
+
* @param {string} newEmail - The new email address
|
|
34
|
+
*/
|
|
35
|
+
async function updateContactEmail(contactId, newEmail) {
|
|
36
|
+
if (!newEmail) {
|
|
37
|
+
throw new Error('New email is required');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return await updateContactInfo(
|
|
41
|
+
contactId,
|
|
42
|
+
currentInfo => ({
|
|
43
|
+
...currentInfo,
|
|
44
|
+
emails: {
|
|
45
|
+
items: [
|
|
46
|
+
{
|
|
47
|
+
email: newEmail,
|
|
48
|
+
primary: true,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
'update contact email'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Updates contact names in Wix CRM
|
|
59
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
60
|
+
* @param {string} firstName - The new first name
|
|
61
|
+
* @param {string} lastName - The new last name
|
|
62
|
+
*/
|
|
63
|
+
async function updateContactNames(contactId, firstName, lastName) {
|
|
64
|
+
if (!firstName && !lastName) {
|
|
65
|
+
throw new Error('At least one name field is required');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return await updateContactInfo(
|
|
69
|
+
contactId,
|
|
70
|
+
currentInfo => ({
|
|
71
|
+
...currentInfo,
|
|
72
|
+
name: {
|
|
73
|
+
first: firstName || currentInfo?.name?.first || '',
|
|
74
|
+
last: lastName || currentInfo?.name?.last || '',
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
'update contact names'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Update fields if they have changed
|
|
83
|
+
* @param {Array} existingValues - Current values for comparison
|
|
84
|
+
* @param {Array} newValues - New values to compare against
|
|
85
|
+
* @param {Function} updater - Function to call if values changed
|
|
86
|
+
* @param {Function} argsBuilder - Function to build arguments for updater
|
|
87
|
+
*/
|
|
88
|
+
const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
|
|
89
|
+
const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
|
|
90
|
+
if (!hasChanged) return null;
|
|
91
|
+
return updater(...argsBuilder(newValues));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Updates member contact information in CRM if fields have changed
|
|
96
|
+
* @param {Object} data - New member data
|
|
97
|
+
* @param {Object} existingMemberData - Existing member data
|
|
98
|
+
*/
|
|
99
|
+
const updateMemberContactInfo = async (data, existingMemberData) => {
|
|
100
|
+
const { contactId } = existingMemberData;
|
|
101
|
+
|
|
102
|
+
const updateConfig = [
|
|
103
|
+
{
|
|
104
|
+
fields: ['contactFormEmail'],
|
|
105
|
+
updater: updateContactEmail,
|
|
106
|
+
args: ([email]) => [contactId, email],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
fields: ['firstName', 'lastName'],
|
|
110
|
+
updater: updateContactNames,
|
|
111
|
+
args: ([firstName, lastName]) => [contactId, firstName, lastName],
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
const updatePromises = updateConfig
|
|
116
|
+
.map(({ fields, updater, args }) => {
|
|
117
|
+
const existingValues = fields.map(field => existingMemberData[field]);
|
|
118
|
+
const newValues = fields.map(field => data[field]);
|
|
119
|
+
return updateIfChanged(existingValues, newValues, updater, args);
|
|
120
|
+
})
|
|
121
|
+
.filter(Boolean);
|
|
122
|
+
|
|
123
|
+
await Promise.all(updatePromises);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
updateMemberContactInfo,
|
|
128
|
+
};
|
package/backend/index.js
CHANGED
|
@@ -8,4 +8,6 @@ module.exports = {
|
|
|
8
8
|
...require('./pac-api-methods'), //TODO: remove it once we finish NPM movement
|
|
9
9
|
...require('./members-area-methods'), //TODO: remove it once we finish NPM movement
|
|
10
10
|
...require('./members-data-methods'), //TODO: remove it once we finish NPM movement
|
|
11
|
+
...require('./cms-data-methods'), //TODO: remove it once we finish NPM movement
|
|
12
|
+
...require('./sso-methods'),
|
|
11
13
|
};
|
|
@@ -31,6 +31,11 @@ const createSiteMember = async memberDetails => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
const getCurrentMember = async () => {
|
|
35
|
+
const member = await members.getCurrentMember();
|
|
36
|
+
return member.member;
|
|
37
|
+
};
|
|
38
|
+
|
|
34
39
|
/**
|
|
35
40
|
* Updates Wix member login email if the member has a contactId (registered Wix member)
|
|
36
41
|
* @param {Object} member - Member object with contactId and email
|
|
@@ -79,5 +84,6 @@ async function updateWixMemberLoginEmail(member, result = {}) {
|
|
|
79
84
|
|
|
80
85
|
module.exports = {
|
|
81
86
|
createSiteMember,
|
|
87
|
+
getCurrentMember,
|
|
82
88
|
updateWixMemberLoginEmail,
|
|
83
89
|
};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
const { COLLECTIONS } = require('../public/consts');
|
|
2
2
|
|
|
3
|
+
const { updateMemberContactInfo } = require('./contacts-methods');
|
|
4
|
+
const { MEMBER_ACTIONS } = require('./daily-pull');
|
|
3
5
|
const { wixData } = require('./elevated-modules');
|
|
4
6
|
const { createSiteMember } = require('./members-area-methods');
|
|
5
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
createBatches,
|
|
9
|
+
normalizeUrlForComparison,
|
|
10
|
+
queryAllItems,
|
|
11
|
+
generateGeoHash,
|
|
12
|
+
} = require('./utils');
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* Retrieves member data by member ID
|
|
@@ -50,10 +57,9 @@ async function createContactAndMemberIfNew(memberData) {
|
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @
|
|
56
|
-
* @returns {Promise<Object>} - Bulk save operation result
|
|
60
|
+
/** Performs bulk save operation for member data
|
|
61
|
+
* @param { Array } memberDataList - Array of member data objects to save
|
|
62
|
+
* @returns { Promise < Object >} - Bulk save operation result
|
|
57
63
|
*/
|
|
58
64
|
async function bulkSaveMembers(memberDataList) {
|
|
59
65
|
if (!Array.isArray(memberDataList) || memberDataList.length === 0) {
|
|
@@ -71,6 +77,7 @@ async function bulkSaveMembers(memberDataList) {
|
|
|
71
77
|
throw new Error(`Bulk save failed: ${error.message}`);
|
|
72
78
|
}
|
|
73
79
|
}
|
|
80
|
+
|
|
74
81
|
/**
|
|
75
82
|
* Retrieves member data by member ID
|
|
76
83
|
* @param {string} memberId - The member ID to search for
|
|
@@ -181,9 +188,88 @@ async function getMemberByContactId(contactId) {
|
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Saves member registration data
|
|
193
|
+
* @param {Object} data - Member data to save
|
|
194
|
+
* @param {string} id - Member ID
|
|
195
|
+
* @returns {Promise<Object>} Result object with type and data/error
|
|
196
|
+
*/
|
|
197
|
+
async function saveRegistrationData(data, id) {
|
|
198
|
+
try {
|
|
199
|
+
console.log(' saveRegistrationData data._id', data._id);
|
|
200
|
+
console.log(' saveRegistrationData id', id);
|
|
201
|
+
if (data._id !== id) return { type: 'notAuthorized' };
|
|
202
|
+
|
|
203
|
+
if (data.url) {
|
|
204
|
+
const isDuplicate = await urlExists(data.url, data.memberId);
|
|
205
|
+
|
|
206
|
+
if (isDuplicate) {
|
|
207
|
+
return {
|
|
208
|
+
type: 'error',
|
|
209
|
+
error: 'URL slug is already taken. Please choose a different one.',
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (data.addresses && Array.isArray(data.addresses)) {
|
|
215
|
+
data.locHash = generateGeoHash(data.addresses);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const existingMemberData = await findMemberByWixDataId(id);
|
|
219
|
+
|
|
220
|
+
await updateMemberContactInfo(data, existingMemberData);
|
|
221
|
+
|
|
222
|
+
const saveData = await wixData.update(COLLECTIONS.MEMBERS_DATA, data);
|
|
223
|
+
return {
|
|
224
|
+
type: 'success',
|
|
225
|
+
saveData,
|
|
226
|
+
};
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error(error);
|
|
229
|
+
return {
|
|
230
|
+
type: 'error',
|
|
231
|
+
error,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Checks if a URL already exists in the database for a different member (case-insensitive)
|
|
238
|
+
* @param {string} url - The URL to check
|
|
239
|
+
* @param {string|number} excludeMemberId - Member ID to exclude from the check
|
|
240
|
+
* @returns {Promise<boolean>} - True if URL exists for another member
|
|
241
|
+
*/
|
|
242
|
+
async function urlExists(url, excludeMemberId) {
|
|
243
|
+
if (!url) return false;
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
let query = wixData
|
|
247
|
+
.query(COLLECTIONS.MEMBERS_DATA)
|
|
248
|
+
.contains('url', url)
|
|
249
|
+
.ne('action', MEMBER_ACTIONS.DROP);
|
|
250
|
+
|
|
251
|
+
if (excludeMemberId) {
|
|
252
|
+
query = query.ne('memberId', excludeMemberId);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const { items } = await query.find();
|
|
256
|
+
|
|
257
|
+
// Case-insensitive comparison
|
|
258
|
+
const matchingMembers = items.filter(
|
|
259
|
+
item => item.url && item.url.toLowerCase() === url.toLowerCase()
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
return matchingMembers.length > 0;
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error('Error checking URL existence:', error);
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
184
269
|
module.exports = {
|
|
185
270
|
findMemberByWixDataId,
|
|
186
271
|
createContactAndMemberIfNew,
|
|
272
|
+
saveRegistrationData,
|
|
187
273
|
bulkSaveMembers,
|
|
188
274
|
findMemberById,
|
|
189
275
|
getMemberBySlug,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const { CONFIG_KEYS } = require('./consts');
|
|
2
|
+
const { MEMBER_ACTIONS } = require('./daily-pull');
|
|
3
|
+
const { getCurrentMember } = require('./members-area-methods');
|
|
4
|
+
const { getMemberByContactId } = require('./members-data-methods');
|
|
5
|
+
const {
|
|
6
|
+
formatDateToMonthYear,
|
|
7
|
+
getAddressDisplayOptions,
|
|
8
|
+
isStudent,
|
|
9
|
+
getSiteConfigs,
|
|
10
|
+
} = require('./utils');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validates member token and retrieves member data
|
|
14
|
+
* @param {string} memberIdInput - The member ID to validate
|
|
15
|
+
* @returns {Promise<{memberData: Object|null, isValid: boolean}>} Validation result with member data
|
|
16
|
+
*/
|
|
17
|
+
async function validateMemberToken(memberIdInput) {
|
|
18
|
+
const invalidTokenResponse = { memberData: null, isValid: false };
|
|
19
|
+
|
|
20
|
+
if (!memberIdInput) {
|
|
21
|
+
return invalidTokenResponse;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const member = await getCurrentMember();
|
|
26
|
+
if (!member || !member._id) {
|
|
27
|
+
console.log(
|
|
28
|
+
'member not found from members.getCurrentMember() for memberIdInput',
|
|
29
|
+
memberIdInput
|
|
30
|
+
);
|
|
31
|
+
return invalidTokenResponse;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const [dbMember, siteConfigs] = await Promise.all([
|
|
35
|
+
getMemberByContactId(member._id),
|
|
36
|
+
getSiteConfigs(),
|
|
37
|
+
]);
|
|
38
|
+
const siteAssociation = siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION];
|
|
39
|
+
const membersExternalPortalUrl = siteConfigs[CONFIG_KEYS.MEMBERS_EXTERNAL_PORTAL_URL];
|
|
40
|
+
console.log('dbMember by contact id is:', dbMember);
|
|
41
|
+
console.log('member._id', member._id);
|
|
42
|
+
|
|
43
|
+
if (!dbMember?._id) {
|
|
44
|
+
const errorMessage = `No record found in DB for logged in Member [Corrupted Data - Duplicate Members? ] - There is no match in DB for currentMember: ${JSON.stringify(
|
|
45
|
+
{ memberIdInput, currentMemberId: member._id }
|
|
46
|
+
)}`;
|
|
47
|
+
console.error(errorMessage);
|
|
48
|
+
throw new Error('CORRUPTED_MEMBER_DATA');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(`Id found in DB for memberIdInput :${memberIdInput} is ${dbMember?._id}`);
|
|
52
|
+
|
|
53
|
+
const memberData = dbMember;
|
|
54
|
+
|
|
55
|
+
// Format membership dates
|
|
56
|
+
memberData.memberships = memberData.memberships.map(membership => ({
|
|
57
|
+
...membership,
|
|
58
|
+
membersince: formatDateToMonthYear(membership.membersince),
|
|
59
|
+
isSiteAssociation: membership.association === siteAssociation,
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
const savedMemberId = memberData?._id;
|
|
63
|
+
const isValid = savedMemberId === memberIdInput;
|
|
64
|
+
|
|
65
|
+
if (!savedMemberId || !isValid) {
|
|
66
|
+
return invalidTokenResponse;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if member is dropped
|
|
70
|
+
if (memberData.action === MEMBER_ACTIONS.DROP) {
|
|
71
|
+
return invalidTokenResponse;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add computed properties
|
|
75
|
+
memberData.addressDisplayOption = getAddressDisplayOptions(memberData);
|
|
76
|
+
console.log('memberData', memberData);
|
|
77
|
+
memberData.isStudent = isStudent(memberData);
|
|
78
|
+
|
|
79
|
+
return { memberData, isValid, membersExternalPortalUrl };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('Error in validateMemberToken:', error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = {
|
|
87
|
+
validateMemberToken,
|
|
88
|
+
};
|
package/backend/utils.js
CHANGED
|
@@ -4,6 +4,7 @@ const { COLLECTIONS } = require('../public/consts');
|
|
|
4
4
|
|
|
5
5
|
const { CONFIG_KEYS, GEO_HASH_PRECISION } = require('./consts');
|
|
6
6
|
const { wixData } = require('./elevated-modules');
|
|
7
|
+
const { urlExists } = require('./members-data-methods');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Retrieves site configuration values from the database
|
|
@@ -41,6 +42,46 @@ const retrieveAllItems = async collectionName => {
|
|
|
41
42
|
return allItems;
|
|
42
43
|
};
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Format date to Month Year string
|
|
47
|
+
* @param {string} dateString - The date string to format
|
|
48
|
+
* @returns {string} Formatted date (e.g., "January 2024")
|
|
49
|
+
*/
|
|
50
|
+
function formatDateToMonthYear(dateString) {
|
|
51
|
+
if (!dateString) return '';
|
|
52
|
+
|
|
53
|
+
const date = new Date(dateString);
|
|
54
|
+
if (isNaN(date.getTime())) return '';
|
|
55
|
+
const options = { year: 'numeric', month: 'long' };
|
|
56
|
+
return date.toLocaleDateString('en-US', options);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if member is a student
|
|
61
|
+
* @param {Object} member - The member object
|
|
62
|
+
* @returns {boolean} True if member has student membership
|
|
63
|
+
*/
|
|
64
|
+
function isStudent(member) {
|
|
65
|
+
const memberships = member?.memberships;
|
|
66
|
+
if (!Array.isArray(memberships)) return false;
|
|
67
|
+
|
|
68
|
+
return memberships.some(membership => membership.membertype === 'student');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get address display options for member
|
|
73
|
+
* @param {Object} member - The member object
|
|
74
|
+
* @returns {Array} Address display options
|
|
75
|
+
*/
|
|
76
|
+
function getAddressDisplayOptions(member) {
|
|
77
|
+
const addresses = member.addresses || [];
|
|
78
|
+
const displayOptions = member.addressDisplayOption || [];
|
|
79
|
+
if (addresses.length === 1 && addresses[0].key) {
|
|
80
|
+
return [{ key: addresses[0].key, isMain: true }];
|
|
81
|
+
}
|
|
82
|
+
return displayOptions;
|
|
83
|
+
}
|
|
84
|
+
|
|
44
85
|
const queryAllItems = async query => {
|
|
45
86
|
console.log('start query');
|
|
46
87
|
let oldResults = await query.find();
|
|
@@ -87,6 +128,28 @@ const normalizeUrlForComparison = url => {
|
|
|
87
128
|
return url.toLowerCase().replace(/-\d+$/, '');
|
|
88
129
|
};
|
|
89
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Checks URL uniqueness for a member
|
|
133
|
+
* @param {string} url - The URL to check
|
|
134
|
+
* @param {string} memberId - The member ID to exclude from the check
|
|
135
|
+
* @returns {Promise<Object>} Result object with isUnique boolean
|
|
136
|
+
*/
|
|
137
|
+
async function checkUrlUniqueness(url, memberId) {
|
|
138
|
+
if (!url || !memberId) {
|
|
139
|
+
throw new Error('Missing required parameters: url and memberId are required');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
const trimmedUrl = url.trim();
|
|
144
|
+
const exists = await urlExists(trimmedUrl, memberId);
|
|
145
|
+
|
|
146
|
+
return { isUnique: !exists };
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error('Error checking URL uniqueness:', error);
|
|
149
|
+
throw new Error(`Failed to check URL uniqueness: ${error.message}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
90
153
|
module.exports = {
|
|
91
154
|
getSiteConfigs,
|
|
92
155
|
retrieveAllItems,
|
|
@@ -95,4 +158,8 @@ module.exports = {
|
|
|
95
158
|
isValidArray,
|
|
96
159
|
normalizeUrlForComparison,
|
|
97
160
|
queryAllItems,
|
|
161
|
+
checkUrlUniqueness,
|
|
162
|
+
formatDateToMonthYear,
|
|
163
|
+
isStudent,
|
|
164
|
+
getAddressDisplayOptions,
|
|
98
165
|
};
|
package/eslint.config.js
CHANGED
|
@@ -31,7 +31,7 @@ module.exports = [
|
|
|
31
31
|
// Error prevention
|
|
32
32
|
'no-var': 'error',
|
|
33
33
|
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
|
34
|
-
'no-console': ['warn', { allow: ['warn', 'error', 'log', 'info'] }],
|
|
34
|
+
'no-console': ['warn', { allow: ['warn', 'error', 'log', 'info', 'group', 'groupEnd'] }],
|
|
35
35
|
'no-debugger': 'warn',
|
|
36
36
|
'no-duplicate-imports': 'error',
|
|
37
37
|
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abmp-npm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.53",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"@wix/secrets": "^1.0.62",
|
|
35
35
|
"@wix/site-location": "^1.31.0",
|
|
36
36
|
"@wix/site-window": "^1.44.0",
|
|
37
|
+
"lodash": "^4.17.21",
|
|
37
38
|
"ngeohash": "^0.6.3",
|
|
38
39
|
"phone": "^3.1.67",
|
|
39
40
|
"psdev-task-manager": "1.1.7",
|