abmp-npm 2.0.76 → 2.0.78

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 (99) hide show
  1. package/package.json +8 -1
  2. package/pages/Home.js +27 -55
  3. package/pages/index.js +0 -1
  4. package/public/Utils/personalDetailsUtils.js +5 -1
  5. package/public/Utils/sharedUtils.js +32 -0
  6. package/public/consts.js +0 -1
  7. package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
  8. package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
  9. package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
  10. package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
  11. package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
  12. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  13. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  14. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
  15. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  16. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
  17. package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
  18. package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
  19. package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
  20. package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
  21. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
  22. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
  23. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
  24. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
  25. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
  26. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
  27. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
  28. package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
  29. package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
  30. package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
  31. package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
  32. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
  33. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
  34. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
  35. package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
  36. package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
  37. package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
  38. package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
  39. package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
  40. package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
  41. package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
  42. package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
  43. package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
  44. package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
  45. package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
  46. package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
  47. package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
  48. package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
  49. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
  50. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
  51. package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
  52. package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
  53. package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
  54. package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
  55. package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
  56. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
  57. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
  58. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
  59. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
  60. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
  61. package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
  62. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  63. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
  64. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
  65. package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
  66. package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
  67. package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
  68. package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
  69. package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
  70. package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
  71. package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
  72. package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
  73. package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
  74. package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
  75. package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
  76. package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
  77. package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
  78. package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
  79. package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
  80. package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
  81. package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
  82. package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
  83. package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
  84. package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
  85. package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
  86. package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
  87. package/.husky/pre-commit +0 -19
  88. package/.prettierignore +0 -7
  89. package/.prettierrc.json +0 -16
  90. package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  91. package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  92. package/backend/__tests__/login-email-sync.test.js +0 -49
  93. package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  94. package/backend/__tests__/url-uniqueness.test.js +0 -194
  95. package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  96. package/dev-only-scripts/find-duplicate-ids.js +0 -159
  97. package/dev-only-scripts/find-duplicate-urls.js +0 -201
  98. package/eslint.config.js +0 -120
  99. package/pages/contactForLocation.js +0 -28
@@ -1,161 +0,0 @@
1
- const { taskManager } = require('psdev-task-manager');
2
-
3
- const { CONFIG_KEYS } = require('../consts');
4
- const { fetchPACMembers } = require('../pac-api-methods');
5
- const { TASKS_NAMES } = require('../tasks/consts');
6
- const { getSiteConfigs } = require('../utils');
7
-
8
- const { bulkProcessAndSaveMemberData } = require('./bulk-process-methods');
9
- const { MEMBER_ACTIONS } = require('./consts');
10
- const { isUpdatedMember, isSiteAssociatedMember } = require('./utils');
11
-
12
- const filterLicensesByAssociation = (member, siteAssociation) => {
13
- if (!member?.licenses || !Array.isArray(member.licenses)) {
14
- return member;
15
- }
16
- const filteredLicenses = member.licenses.filter(license => {
17
- if (!license || !license.association) {
18
- return true;
19
- }
20
- return license.association === siteAssociation;
21
- });
22
- return {
23
- ...member,
24
- licenses: filteredLicenses,
25
- };
26
- };
27
-
28
- async function syncMembersDataPerAction(taskData) {
29
- const { action, backupDate, isTestEnvironment, includeNone } = taskData;
30
- try {
31
- const firstPageResponse = await fetchPACMembers({
32
- page: 1,
33
- action,
34
- backupDate,
35
- isTestEnvironment,
36
- });
37
-
38
- if (
39
- !firstPageResponse ||
40
- !firstPageResponse.results ||
41
- firstPageResponse.results.length === 0
42
- ) {
43
- return {
44
- success: true,
45
- totalPagesProcessed: 0,
46
- lastPageProcessed: 0,
47
- completedAt: new Date().toISOString(),
48
- message: 'No data found',
49
- };
50
- }
51
-
52
- // Calculate total pages from API response
53
- const totalResults = firstPageResponse.total_results || 0;
54
- const perPage = firstPageResponse.results.length;
55
- const totalPages = firstPageResponse.total_pages || 0;
56
-
57
- // Cap at 1000 pages as safety measure
58
- const pagesToProcess = Math.min(totalPages, 1000);
59
-
60
- console.log(
61
- `Scheduling ${pagesToProcess} pages for processing (${totalResults} total records, ${perPage} per page)`
62
- );
63
-
64
- // Schedule tasks for all pages at once
65
- const toScheduleTasks = Array.from(
66
- { length: pagesToProcess },
67
- (_, i) => i + 1 // API expects page number to start from 1
68
- ).map(pageNumber => ({
69
- name: TASKS_NAMES.SyncMembers,
70
- data: {
71
- pageNumber,
72
- action,
73
- ...(backupDate ? { backupDate } : {}),
74
- ...(isTestEnvironment ? { isTestEnvironment } : {}),
75
- ...(includeNone ? { includeNone } : {}),
76
- },
77
- type: 'scheduled',
78
- }));
79
-
80
- // Wait for all scheduling to complete
81
- await taskManager().scheduleInBulk(toScheduleTasks);
82
-
83
- return {
84
- success: true,
85
- totalPagesProcessed: pagesToProcess,
86
- lastPageProcessed: pagesToProcess,
87
- totalRecords: totalResults,
88
- recordsPerPage: perPage,
89
- completedAt: new Date().toISOString(),
90
- };
91
- } catch (error) {
92
- throw new Error(`Synchronization failed: ${error.message}`);
93
- }
94
- }
95
-
96
- /**
97
- * Synchronizes a single page of member data
98
- * @param {Object} taskObject - Task object containing page data
99
- * @returns {Promise<Object>} - Page synchronization result
100
- */
101
- async function synchronizeSinglePage(taskObject) {
102
- const { pageNumber, action, backupDate, isTestEnvironment, includeNone } = taskObject.data;
103
- try {
104
- const [siteAssociation, memberDataResponse] = await Promise.all([
105
- getSiteConfigs(CONFIG_KEYS.SITE_ASSOCIATION),
106
- fetchPACMembers({
107
- page: pageNumber,
108
- action,
109
- backupDate,
110
- isTestEnvironment,
111
- }),
112
- ]);
113
- if (
114
- !memberDataResponse ||
115
- !memberDataResponse.results ||
116
- memberDataResponse.results.length === 0
117
- ) {
118
- throw new Error(`No data found for page ${pageNumber}`);
119
- }
120
- const toSyncMembers = memberDataResponse.results.filter(member => {
121
- if (!isSiteAssociatedMember(member, siteAssociation)) {
122
- return false;
123
- }
124
- if (action === MEMBER_ACTIONS.NONE && includeNone) {
125
- return true;
126
- }
127
- return isUpdatedMember(member);
128
- });
129
- const toSyncMembersWithFilteredLicenses = toSyncMembers.map(member =>
130
- filterLicensesByAssociation(member, siteAssociation)
131
- );
132
- if (toSyncMembers.length === 0) {
133
- return {
134
- success: true,
135
- pageNumber,
136
- totalPageSize: memberDataResponse.results.length,
137
- filteredPageSize: toSyncMembers.length,
138
- message: `No to be updated, or members of association: '${siteAssociation}' found`,
139
- };
140
- }
141
- const result = await bulkProcessAndSaveMemberData({
142
- memberDataList: toSyncMembersWithFilteredLicenses,
143
- currentPageNumber: pageNumber,
144
- });
145
-
146
- return {
147
- success: true,
148
- pageNumber,
149
- totalPageSize: memberDataResponse.results.length,
150
- filteredPageSize: toSyncMembers.length,
151
- ...result,
152
- };
153
- } catch (error) {
154
- throw new Error(`Page ${pageNumber} synchronization failed: ${error.message}`);
155
- }
156
- }
157
-
158
- module.exports = {
159
- syncMembersDataPerAction,
160
- synchronizeSinglePage,
161
- };
@@ -1,151 +0,0 @@
1
- const { LOGIN_EMAIL_SYNC_STATUS } = require('../consts');
2
- const { updateWixMemberLoginEmail } = require('../members-area-methods');
3
- const { extractUrlCounter } = require('../utils');
4
-
5
- const { MEMBER_ACTIONS } = require('./consts');
6
-
7
- const isUpdatedMember = member => member.action !== MEMBER_ACTIONS.NONE;
8
- const isSiteAssociatedMember = (member, siteAssociation) =>
9
- member.memberships.some(membership => membership.association === siteAssociation);
10
-
11
- /**
12
- * Attempts to change Wix login emails for the given members and returns one structured
13
- * outcome per member (see updateWixMemberLoginEmail). Never throws for an individual member.
14
- * @param {Array} toChangeWixMembersEmails
15
- * @returns {Promise<Array>} outcomes
16
- */
17
- const changeWixMembersEmails = async toChangeWixMembersEmails => {
18
- console.log(
19
- `[loginEmailSync] changing login emails for ${toChangeWixMembersEmails.length} members with ids: [${toChangeWixMembersEmails.map(member => member.memberId).join(', ')}]`
20
- );
21
- const outcomes = await Promise.all(
22
- toChangeWixMembersEmails.map(member => updateWixMemberLoginEmail(member))
23
- );
24
- const summary = outcomes.reduce((acc, outcome) => {
25
- acc[outcome.status] = (acc[outcome.status] || 0) + 1;
26
- return acc;
27
- }, {});
28
- console.log(`[loginEmailSync] results summary: ${JSON.stringify(summary)}`);
29
- return outcomes;
30
- };
31
-
32
- /**
33
- * Summarizes login-email sync outcomes for manual handling via the task result.
34
- * Pure function so it can be unit-tested without Wix.
35
- * @param {Array} outcomes - from updateWixMemberLoginEmail / changeWixMembersEmails
36
- * @returns {{ failedMemberIds: Set, failures: Array }} set of failed memberIds (whose CMS login
37
- * email must be left unchanged) and the failure records to surface in the task result
38
- */
39
- const summarizeLoginEmailOutcomes = (outcomes = []) => {
40
- const failedMemberIds = new Set();
41
- const failures = [];
42
- outcomes.forEach(outcome => {
43
- if (outcome.status === LOGIN_EMAIL_SYNC_STATUS.FAILED) {
44
- failedMemberIds.add(outcome.memberId);
45
- failures.push({
46
- memberId: outcome.memberId,
47
- wixMemberId: outcome.wixMemberId,
48
- desiredEmail: outcome.desiredEmail,
49
- error: outcome.error || 'unknown error',
50
- });
51
- }
52
- });
53
- return { failedMemberIds, failures };
54
- };
55
-
56
- const extractBaseUrl = url => {
57
- if (!url) return url;
58
- const lastCounter = extractUrlCounter(url);
59
- if (lastCounter > 0) {
60
- // Remove the numeric counter to get the base URL
61
- return url.split('-').slice(0, -1).join('-');
62
- }
63
- // No counter found, return the URL as-is
64
- return url;
65
- };
66
- const incrementUrlCounter = (existingUrl, baseUrl) => {
67
- if (!existingUrl || !baseUrl) {
68
- return baseUrl;
69
- }
70
- // Normalize for comparison (case-insensitive)
71
- const normalizedExisting = existingUrl.toLowerCase();
72
- const normalizedBase = baseUrl.toLowerCase();
73
-
74
- if (
75
- normalizedExisting === normalizedBase ||
76
- normalizedExisting.startsWith(`${normalizedBase}-`)
77
- ) {
78
- console.log(
79
- `Found member with same url ${existingUrl} for baseUrl ${baseUrl}, increasing counter by 1`
80
- );
81
- const lastCounter = Math.max(0, extractUrlCounter(existingUrl));
82
- return `${baseUrl}-${lastCounter + 1}`;
83
- }
84
-
85
- // No conflict, return baseUrl with counter 1 to be safe
86
- return `${baseUrl}-1`;
87
- };
88
- /**
89
- * Validates core member data requirements
90
- * @param {Object} inputMemberData - Raw member data from API to validate
91
- * @returns {boolean} - True if all required fields are valid, false otherwise
92
- */
93
- const validateCoreMemberData = inputMemberData => {
94
- // Check memberid
95
- if (!inputMemberData?.memberid) {
96
- console.warn('validateCoreMemberData: Missing required field - memberid is mandatory');
97
- return false;
98
- }
99
-
100
- // Check email
101
- if (
102
- !inputMemberData?.email ||
103
- typeof inputMemberData.email !== 'string' ||
104
- !inputMemberData.email.trim()
105
- ) {
106
- console.warn(
107
- 'validateCoreMemberData: Missing required field - email (valid string) is mandatory'
108
- );
109
- return false;
110
- }
111
-
112
- // Check memberships
113
- if (
114
- !inputMemberData?.memberships ||
115
- !Array.isArray(inputMemberData.memberships) ||
116
- inputMemberData.memberships.length === 0
117
- ) {
118
- console.warn(
119
- 'validateCoreMemberData: Missing required field - memberships (non-empty array) is mandatory'
120
- );
121
- return false;
122
- }
123
-
124
- return true;
125
- };
126
-
127
- const containsNonEnglish = str => /[^a-zA-Z0-9-]/.test(str); // if it contains any non-english characters or invalid URL chars, test1 is allowed, hyphens are allowed
128
-
129
- /**
130
- * Creates a full name from first and last name components
131
- * @param {string} firstName - First name
132
- * @param {string} lastName - Last name
133
- * @returns {string} - Combined full name
134
- */
135
- const createFullName = (firstName, lastName) => {
136
- const trimmedFirst = firstName?.trim() || '';
137
- const trimmedLast = lastName?.trim() || '';
138
- return `${trimmedFirst} ${trimmedLast}`.trim();
139
- };
140
-
141
- module.exports = {
142
- isUpdatedMember,
143
- isSiteAssociatedMember,
144
- changeWixMembersEmails,
145
- summarizeLoginEmailOutcomes,
146
- validateCoreMemberData,
147
- containsNonEnglish,
148
- createFullName,
149
- incrementUrlCounter,
150
- extractBaseUrl,
151
- };
@@ -1,29 +0,0 @@
1
- const { taskManager, TASK_TYPE } = require('psdev-task-manager');
2
-
3
- const { COMPILED_FILTERS_FIELDS } = require('./consts');
4
- const { TASKS_NAMES } = require('./tasks/consts');
5
-
6
- const scheduleCompileFiltersTask = field =>
7
- taskManager().schedule({
8
- name: TASKS_NAMES.CompileFiltersOptions,
9
- data: { field },
10
- type: TASK_TYPE.SCHEDULED,
11
- });
12
-
13
- function scheduleCompileInterestsTask() {
14
- return scheduleCompileFiltersTask(COMPILED_FILTERS_FIELDS.COMPILED_AREAS_OF_PRACTICES);
15
- }
16
-
17
- function scheduleCompileStatesTask() {
18
- return scheduleCompileFiltersTask(COMPILED_FILTERS_FIELDS.COMPILED_STATE_LIST);
19
- }
20
-
21
- function scheduleCompileCitiesTask() {
22
- return scheduleCompileFiltersTask(COMPILED_FILTERS_FIELDS.COMPILED_STATE_CITY_MAP);
23
- }
24
-
25
- module.exports = {
26
- scheduleCompileInterestsTask,
27
- scheduleCompileStatesTask,
28
- scheduleCompileCitiesTask,
29
- };
@@ -1,58 +0,0 @@
1
- const { COLLECTIONS } = require('../public/consts');
2
-
3
- const { ensureUniqueUrlsInBatch } = require('./daily-pull/bulk-process-methods');
4
- const { ensureUniqueUrl } = require('./daily-pull/process-member-methods');
5
- const { wixData } = require('./elevated-modules');
6
- const { bulkSaveMembers } = require('./members-data-methods');
7
- const { queryAllItems } = require('./utils');
8
-
9
- async function deduplicateURls(collectionName, duplicateUrlsList) {
10
- const query = await wixData.query(collectionName).hasSome('url', duplicateUrlsList).limit(1000);
11
- const membersWithSameUrl = await queryAllItems(query);
12
-
13
- console.log({ membersWithSameUrl });
14
- const membersWithUniqueUrls = await ensureUniqueUrlsInBatch(membersWithSameUrl);
15
- console.log({ membersWithUniqueUrls });
16
- const deduplicatedUrls = membersWithUniqueUrls.map(m => m.url);
17
- console.log({ deduplicatedUrls });
18
- return await bulkSaveMembers(membersWithUniqueUrls, collectionName);
19
- }
20
-
21
- async function copyContactIdToWixMemberId() {
22
- const query = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('contactId');
23
- const members = await queryAllItems(query);
24
- const updatedMembers = members.map(member => ({
25
- ...member,
26
- wixMemberId: member.contactId,
27
- }));
28
- return await bulkSaveMembers(updatedMembers, COLLECTIONS.MEMBERS_DATA);
29
- }
30
-
31
- async function createMissingUrls() {
32
- const query = wixData.query(COLLECTIONS.MEMBERS_DATA).isEmpty('url');
33
- const members = await queryAllItems(query);
34
- console.log(
35
- 'membersWithoutUrls info',
36
- JSON.stringify({
37
- count: members.length,
38
- membersIds: members.map(m => m.memberId),
39
- })
40
- );
41
-
42
- const membersWithGeneratedUrlsPromises = members.map(async member => ({
43
- ...member,
44
- url: await ensureUniqueUrl({
45
- url: member.url,
46
- memberId: member.memberId,
47
- fullName: member.fullName,
48
- }),
49
- }));
50
- const membersWithGeneratedUrls = await Promise.all(membersWithGeneratedUrlsPromises);
51
- //recheck urls in same batch to avoid duplicates
52
- const uniqueUrlsUpdatedMembers = await ensureUniqueUrlsInBatch(membersWithGeneratedUrls);
53
- const urls = uniqueUrlsUpdatedMembers.map(m => m.url).filter(Boolean);
54
- console.log('unique urls', [...new Set(urls)]);
55
- return await bulkSaveMembers(uniqueUrlsUpdatedMembers, COLLECTIONS.MEMBERS_DATA);
56
- }
57
-
58
- module.exports = { deduplicateURls, copyContactIdToWixMemberId, createMissingUrls };
@@ -1,18 +0,0 @@
1
- const { items } = require('@wix/data');
2
- const { auth } = require('@wix/essentials');
3
-
4
- // @wix/data does not support suppressAuth currently, so we need to elevate it
5
- const wixData = {
6
- insert: auth.elevate(items.insert),
7
- update: auth.elevate(items.update),
8
- bulkInsert: auth.elevate(items.bulkInsert),
9
- query: auth.elevate(items.query),
10
- save: auth.elevate(items.save),
11
- remove: auth.elevate(items.remove),
12
- get: auth.elevate(items.get),
13
- truncate: auth.elevate(items.truncate),
14
- bulkSave: auth.elevate(items.bulkSave),
15
- search: auth.elevate(items.search),
16
- //TODO: add other methods here as needed
17
- };
18
- module.exports = { wixData };
@@ -1,52 +0,0 @@
1
- const { COLLECTIONS } = require('../public/consts');
2
-
3
- const { triggerAutomation } = require('./automations-methods');
4
- const { CONFIG_KEYS } = require('./consts');
5
- const { wixData } = require('./elevated-modules');
6
- const { findMemberByWixDataId, createContactAndMemberIfNew } = require('./members-data-methods');
7
- const { getSiteConfigs } = require('./utils');
8
-
9
- const contactSubmission = async (data, memberDataId) => {
10
- const { firstName, lastName, email, phone, message } = data;
11
- const [memberData, automationEmailTriggerId] = await Promise.all([
12
- findMemberByWixDataId(memberDataId),
13
- getSiteConfigs(CONFIG_KEYS.AUTOMATION_EMAIL_TRIGGER_ID),
14
- ]);
15
- if (!memberData.showContactForm) {
16
- console.log('Member contact form is not enabled for user, skipping contact submission!');
17
- return;
18
- }
19
- let memberContactId = memberData.wixContactId;
20
- if (!memberContactId) {
21
- /**
22
- * Create a member contact here since some members may have never logged in
23
- * and therefore don’t have a contact ID. However, these members can still
24
- * appear in the directory, and site visitors can reach out to them if they’ve
25
- * enabled their contact form. To handle this, we ensure a contact is created for
26
- * them during this flow if it doesn’t already exist.
27
- */
28
- console.info('Member contact id not found for user, creating new contact!');
29
- const member = await createContactAndMemberIfNew(memberData);
30
- memberContactId = member.wixContactId;
31
- }
32
- console.log('memberContactId', memberContactId);
33
- const emailTriggered = await triggerAutomation(automationEmailTriggerId, {
34
- contactId: memberContactId,
35
- name: `${firstName} ${lastName}`,
36
- email: email,
37
- phone: phone,
38
- message: message,
39
- });
40
- data = {
41
- ...data,
42
- phone: Number(data.phone),
43
- memberContactId,
44
- memberEmail: memberData.contactFormEmail,
45
- };
46
- await wixData.insert(COLLECTIONS.CONTACT_US_SUBMISSIONS, data);
47
- return emailTriggered;
48
- };
49
-
50
- module.exports = {
51
- contactSubmission,
52
- };
@@ -1,86 +0,0 @@
1
- const { COLLECTIONS } = require('../../public/consts');
2
- const { clearCollection } = require('../cms-data-methods');
3
- const { CONFIG_KEYS } = require('../consts');
4
- const { getSecret, getSiteConfigs } = require('../utils');
5
-
6
- const { migrateInterests } = require('./interests');
7
-
8
- const createHTTPFunctionsHelpers = wixHTTPFunctionsMethods => {
9
- const { created, serverError, forbidden, ok, badRequest } = wixHTTPFunctionsMethods;
10
- const responseOptions = {
11
- headers: {
12
- 'Content-Type': 'application/json',
13
- },
14
- };
15
-
16
- const isRequestAuthenticated = async request => {
17
- const AUTH_TOKEN = await getSecret('migrate-api-key');
18
- return request.headers.authorization === 'Bearer ' + AUTH_TOKEN;
19
- };
20
-
21
- const withAuth = handler => async request => {
22
- if (!(await isRequestAuthenticated(request))) {
23
- return forbidden({
24
- ...responseOptions,
25
- body: { error: 'Unauthorized' },
26
- });
27
- }
28
- return handler(request);
29
- };
30
-
31
- const migrateInterestsHandler = async _request => {
32
- try {
33
- const result = await migrateInterests();
34
- return created({
35
- ...responseOptions,
36
- body: {
37
- result,
38
- },
39
- });
40
- } catch (error) {
41
- console.error('Error migrating interests:', error);
42
- return serverError(error);
43
- }
44
- };
45
-
46
- const clearCollectionHandler = async request => {
47
- try {
48
- const collectionName = request.query.collectionName;
49
- if (!collectionName || !Object.values(COLLECTIONS).includes(collectionName)) {
50
- return badRequest({
51
- ...responseOptions,
52
- body: { error: 'Invalid collection name' },
53
- });
54
- }
55
- const result = await clearCollection(collectionName);
56
- return ok({
57
- ...responseOptions,
58
- body: {
59
- result,
60
- },
61
- });
62
- } catch (error) {
63
- return serverError(error);
64
- }
65
- };
66
- const getSiteAssociationHandler = async _request => {
67
- try {
68
- const siteAssociation = await getSiteConfigs(CONFIG_KEYS.SITE_ASSOCIATION);
69
- return ok({
70
- ...responseOptions,
71
- body: { siteAssociation },
72
- });
73
- } catch (error) {
74
- console.error('Error getting site association:', error);
75
- return serverError(error);
76
- }
77
- };
78
-
79
- return {
80
- post_migrateInterests: withAuth(migrateInterestsHandler),
81
- delete_clearCollection: withAuth(clearCollectionHandler),
82
- get_getSiteAssociation: withAuth(getSiteAssociationHandler),
83
- };
84
- };
85
-
86
- module.exports = { createHTTPFunctionsHelpers };
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- ...require('./httpFunctions'),
3
- };
@@ -1,35 +0,0 @@
1
- const axios = require('axios');
2
-
3
- const { COLLECTIONS } = require('../../public/consts');
4
- const { clearCollection } = require('../cms-data-methods');
5
- const { CONFIG_KEYS } = require('../consts');
6
- const { wixData } = require('../elevated-modules');
7
- const { getHeaders } = require('../pac-api-methods');
8
- const { getSiteConfigs } = require('../utils');
9
-
10
- const getInterests = async () => {
11
- const [url, headers] = await Promise.all([
12
- getSiteConfigs(CONFIG_KEYS.INTERESTS_API_URL),
13
- getHeaders(),
14
- ]);
15
- try {
16
- const response = await axios.get(url, { headers });
17
- return response.data;
18
- } catch (e) {
19
- console.error('Error getting interests:', e);
20
- throw e;
21
- }
22
- };
23
-
24
- async function migrateInterests() {
25
- const [interests, _] = await Promise.all([
26
- getInterests(),
27
- clearCollection(COLLECTIONS.INTERESTS),
28
- ]);
29
- const interestData = interests.map(val => ({ title: val.interest }));
30
- return await wixData.bulkInsert(COLLECTIONS.INTERESTS, interestData);
31
- }
32
-
33
- module.exports = {
34
- migrateInterests,
35
- };
@@ -1,19 +0,0 @@
1
- module.exports = {
2
- ...require('./forms-methods'),
3
- ...require('./search-filters-methods'),
4
- ...require('./jobs'),
5
- ...require('./consts'), //TODO: remove it once we finish NPM movement
6
- ...require('./utils'), //TODO: remove it once we finish NPM movement
7
- ...require('./daily-pull'), //TODO: remove it once we finish NPM movement
8
- ...require('./pac-api-methods'), //TODO: remove it once we finish NPM movement
9
- ...require('./members-area-methods'), //TODO: remove it once we finish NPM movement
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('./routers'),
13
- ...require('./login'),
14
- ...require('./data-hooks'),
15
- ...require('./http-functions'),
16
- ...require('./dev-only-methods'),
17
- ...require('./tasks/migration-methods'),
18
- ...require('./tasks/url-migration-methods'),
19
- };