sr-npm 1.7.55 → 1.7.56
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/collectionConsts.js +48 -0
- package/backend/consts.js +19 -61
- package/backend/data.js +43 -14
- package/backend/fetchPositionsFromSRAPI.js +27 -14
- package/backend/utils.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const COLLECTIONS = {
|
|
2
|
+
AMOUNT_OF_JOBS_PER_DEPARTMENT: 'AmountOfJobsPerDepartment1',
|
|
3
|
+
CITIES: 'cities1',
|
|
4
|
+
JOBS: 'Jobs1',
|
|
5
|
+
API_KEY: 'ApiKey',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const COLLECTIONS_FIELDS = {
|
|
9
|
+
AMOUNT_OF_JOBS_PER_DEPARTMENT: [
|
|
10
|
+
{key:'title', type: 'TEXT'},
|
|
11
|
+
{ key: 'count', type: 'NUMBER' },
|
|
12
|
+
],
|
|
13
|
+
CITIES: [
|
|
14
|
+
{key:'title', type: 'TEXT'},
|
|
15
|
+
{ key: 'regionCode', type: 'TEXT' },
|
|
16
|
+
{ key: 'city', type: 'TEXT' },
|
|
17
|
+
{key:'location', type: 'OBJECT'},
|
|
18
|
+
{key:'count', type: 'NUMBER'},
|
|
19
|
+
{key:'country', type: 'TEXT'},
|
|
20
|
+
{key:'remote', type: 'TEXT'},
|
|
21
|
+
{key:'countryCode', type: 'TEXT'},
|
|
22
|
+
{key:'manual', type: 'TEXT'},
|
|
23
|
+
{key:'region', type: 'TEXT'},
|
|
24
|
+
{key:'latitude', type: 'NUMBER'},
|
|
25
|
+
{key:'longitude', type: 'NUMBER'},
|
|
26
|
+
],
|
|
27
|
+
JOBS: [
|
|
28
|
+
{key:'location', type: 'OBJECT'},
|
|
29
|
+
{key:'postingStatus', type: 'TEXT'},
|
|
30
|
+
{key:'country', type: 'TEXT'},
|
|
31
|
+
{key:'department', type: 'TEXT'},
|
|
32
|
+
{key:'language', type: 'TEXT'},
|
|
33
|
+
{key:'jobDescription', type: 'OBJECT'},
|
|
34
|
+
{key:'cityText', type: 'TEXT'},
|
|
35
|
+
{key:'departmentref', type: 'REFERENCE', typeMetadata: { reference: { referencedCollectionId: 'AmountOfJobsPerDepartment1' } } },
|
|
36
|
+
{key:'city', type: 'REFERENCE', typeMetadata: { reference: { referencedCollectionId: 'cities1' } } },
|
|
37
|
+
],
|
|
38
|
+
API_KEY: [
|
|
39
|
+
{key:'token', type: 'TEXT'},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
COLLECTIONS,
|
|
47
|
+
COLLECTIONS_FIELDS,
|
|
48
|
+
};
|
package/backend/consts.js
CHANGED
|
@@ -5,21 +5,24 @@ const {
|
|
|
5
5
|
referenceJobsToField,
|
|
6
6
|
} = require('./data');
|
|
7
7
|
const { createCollectionIfMissing } = require('@hisense-staging/velo-npm/backend');
|
|
8
|
+
const { COLLECTIONS, COLLECTIONS_FIELDS } = require('./collectionConsts');
|
|
8
9
|
|
|
9
10
|
const QUERY_MAX_LIMIT = 1000;
|
|
10
11
|
|
|
11
12
|
const TASKS_NAMES = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
SYNC_JOBS: 'syncJobsFromSRAPIToCMS',
|
|
14
|
+
INSERT_JOBS_TO_CMS: 'insertJobsToCMS',
|
|
15
|
+
INSERT_JOBS_DESCRIPTIONS_TO_CMS: 'insertJobsDescriptionsToCMS',
|
|
16
|
+
FILL_JOBS_PER_CITY_COLLECTION: 'fillJobsPerCityCollection',
|
|
17
|
+
FILL_JOBS_PER_DEPARTMENT_COLLECTION: 'fillJobsPerDepartmentCollection',
|
|
18
|
+
REFERENCE_JOBS_TO_LOCATIONS: 'referenceJobsToLocations',
|
|
19
|
+
REFERENCE_JOBS_TO_DEPARTMENT: 'referenceJobsToDepartment',
|
|
20
|
+
CREATE_JOBS_COLLECTION: 'createJobsCollection',
|
|
21
|
+
CREATE_CITIES_COLLECTION: 'createCitiesCollection',
|
|
22
|
+
CREATE_AMOUNT_OF_JOBS_PER_DEPARTMENT_COLLECTION: 'createAmountOfJobsPerDepartmentCollection',
|
|
23
|
+
CREATE_API_KEY_COLLECTION_AND_FILL_IT: 'createApiKeyCollectionAndFillIt',
|
|
24
|
+
}
|
|
25
|
+
|
|
23
26
|
|
|
24
27
|
const TASKS = {
|
|
25
28
|
[TASKS_NAMES.SYNC_JOBS]: {
|
|
@@ -125,61 +128,16 @@ const TASKS = {
|
|
|
125
128
|
},
|
|
126
129
|
};
|
|
127
130
|
|
|
128
|
-
const COLLECTIONS = {
|
|
129
|
-
AMOUNT_OF_JOBS_PER_DEPARTMENT: 'AmountOfJobsPerDepartment1',
|
|
130
|
-
CITIES: 'cities1',
|
|
131
|
-
JOBS: 'Jobs1',
|
|
132
|
-
};
|
|
133
131
|
|
|
134
|
-
const COLLECTIONS_FIELDS = {
|
|
135
|
-
AMOUNT_OF_JOBS_PER_DEPARTMENT: [
|
|
136
|
-
{ key: 'title', type: 'TEXT' },
|
|
137
|
-
{ key: 'count', type: 'NUMBER' },
|
|
138
|
-
],
|
|
139
|
-
CITIES: [
|
|
140
|
-
{ key: 'title', type: 'TEXT' },
|
|
141
|
-
{ key: 'regionCode', type: 'TEXT' },
|
|
142
|
-
{ key: 'city', type: 'TEXT' },
|
|
143
|
-
{ key: 'location', type: 'OBJECT' },
|
|
144
|
-
{ key: 'count', type: 'NUMBER' },
|
|
145
|
-
{ key: 'country', type: 'TEXT' },
|
|
146
|
-
{ key: 'remote', type: 'TEXT' },
|
|
147
|
-
{ key: 'countryCode', type: 'TEXT' },
|
|
148
|
-
{ key: 'manual', type: 'TEXT' },
|
|
149
|
-
{ key: 'region', type: 'TEXT' },
|
|
150
|
-
{ key: 'latitude', type: 'NUMBER' },
|
|
151
|
-
{ key: 'longitude', type: 'NUMBER' },
|
|
152
|
-
],
|
|
153
|
-
JOBS: [
|
|
154
|
-
{ key: 'location', type: 'OBJECT' },
|
|
155
|
-
{ key: 'postingStatus', type: 'TEXT' },
|
|
156
|
-
{ key: 'country', type: 'TEXT' },
|
|
157
|
-
{ key: 'department', type: 'TEXT' },
|
|
158
|
-
{ key: 'language', type: 'TEXT' },
|
|
159
|
-
{ key: 'jobDescription', type: 'OBJECT' },
|
|
160
|
-
{ key: 'cityText', type: 'TEXT' },
|
|
161
|
-
{
|
|
162
|
-
key: 'departmentRef',
|
|
163
|
-
type: 'REFERENCE',
|
|
164
|
-
typeMetadata: { reference: { referencedCollectionId: 'AmountOfJobsPerDepartment1' } },
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
key: 'city',
|
|
168
|
-
type: 'REFERENCE',
|
|
169
|
-
typeMetadata: { reference: { referencedCollectionId: 'cities1' } },
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
};
|
|
173
132
|
|
|
174
133
|
const TASK_TYPE = {
|
|
175
134
|
SCHEDULED: 'scheduled',
|
|
176
135
|
EVENT: 'event',
|
|
177
136
|
};
|
|
178
137
|
|
|
179
|
-
module.exports = {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
QUERY_MAX_LIMIT,
|
|
138
|
+
module.exports = {
|
|
139
|
+
TASKS_NAMES,
|
|
140
|
+
TASK_TYPE,
|
|
141
|
+
TASKS,
|
|
142
|
+
QUERY_MAX_LIMIT
|
|
185
143
|
};
|
package/backend/data.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
const { items: wixData } = require('@wix/data');
|
|
2
2
|
const { fetchPositionsFromSRAPI, fetchJobDescription } = require('./fetchPositionsFromSRAPI');
|
|
3
|
+
const { createCollectionIfMissing } = require('@hisense-staging/velo-npm/backend');
|
|
4
|
+
const { COLLECTIONS, COLLECTIONS_FIELDS } = require('./collectionConsts');
|
|
5
|
+
const { secrets } = require("@wix/secrets");
|
|
6
|
+
const { auth } = require('@wix/essentials');
|
|
3
7
|
const { chunkedBulkOperation, delay, countJobsPerGivenField, fillCityLocation ,prepateToSaveArray,normalizeCityName} = require('./utils');
|
|
4
8
|
const { getAllPositions } = require('./queries');
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
|
|
8
12
|
async function saveJobsDataToCMS() {
|
|
9
|
-
console.log('saveJobsDataToCMS is called');
|
|
10
13
|
const positions = await fetchPositionsFromSRAPI();
|
|
11
|
-
console.log('after fetchPositionsFromSRAPI');
|
|
12
14
|
// bulk insert to jobs collection without descriptions first
|
|
13
15
|
const jobsData = positions.content.map(position => {
|
|
14
16
|
const basicJob = {
|
|
@@ -26,12 +28,9 @@ async function saveJobsDataToCMS() {
|
|
|
26
28
|
return basicJob;
|
|
27
29
|
});
|
|
28
30
|
|
|
29
|
-
console.log('i am here@@@@@@@@ ', );
|
|
30
31
|
const chunkSize = 1000;
|
|
31
32
|
let totalSaved = 0;
|
|
32
33
|
const totalChunks = Math.ceil(jobsData.length / chunkSize);
|
|
33
|
-
console.log('jobsData is ', jobsData);
|
|
34
|
-
console.log('totalChunks is ', totalChunks);
|
|
35
34
|
|
|
36
35
|
console.log(
|
|
37
36
|
`Processing ${jobsData.length} jobs in ${totalChunks} chunks of max ${chunkSize} items each`
|
|
@@ -141,20 +140,20 @@ async function saveJobsDescriptionsAndLocationToCMS() {
|
|
|
141
140
|
}
|
|
142
141
|
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
function iterateOverAllJobs(results, field) {
|
|
144
|
+
const jobsPerField = {};
|
|
145
|
+
const cityLocations = {};
|
|
145
146
|
countJobsPerGivenField(results, field, jobsPerField);
|
|
146
147
|
if (field === 'cityText') {
|
|
147
148
|
fillCityLocation(results, cityLocations);
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
+
return { jobsPerField, cityLocations };
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
async function aggregateJobsByFieldToCMS({ field, collection }) {
|
|
153
154
|
console.log(`counting jobs per ${field}.`);
|
|
154
|
-
const jobsPerField = {};
|
|
155
|
-
const cityLocations = {};
|
|
156
155
|
let results = await getAllPositions();
|
|
157
|
-
|
|
156
|
+
const { jobsPerField, cityLocations } = iterateOverAllJobs(results, field);
|
|
158
157
|
const toSave = prepateToSaveArray(jobsPerField, cityLocations, field);
|
|
159
158
|
if (toSave.length === 0) {
|
|
160
159
|
console.log('No jobs found.');
|
|
@@ -253,9 +252,39 @@ function fetchJobLocation(jobDetails) {
|
|
|
253
252
|
return jobLocation;
|
|
254
253
|
}
|
|
255
254
|
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
function getSmartToken() {
|
|
258
|
+
const elevatedGetSecretValue = auth.elevate(secrets.getSecretValue);
|
|
259
|
+
return elevatedGetSecretValue("x-smarttoken")
|
|
260
|
+
.then((secret) => {
|
|
261
|
+
return secret;
|
|
262
|
+
})
|
|
263
|
+
.catch((error) => {
|
|
264
|
+
console.error(error);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
async function createApiKeyCollectionAndFillIt() {
|
|
270
|
+
console.log("Creating ApiKey collection and filling it with the smart token");
|
|
271
|
+
await createCollectionIfMissing(COLLECTIONS.API_KEY, COLLECTIONS_FIELDS.API_KEY,null,'singleItem');
|
|
272
|
+
console.log("Getting the smart token");
|
|
273
|
+
const token = await getSmartToken();
|
|
274
|
+
console.log("token is : ", token);
|
|
275
|
+
console.log("Inserting the smart token into the ApiKey collection");
|
|
276
|
+
await wixData.insert(COLLECTIONS.API_KEY, {
|
|
277
|
+
token: token.value
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
console.log("Smart token inserted into the ApiKey collection");
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
256
284
|
module.exports = {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
285
|
+
saveJobsDataToCMS,
|
|
286
|
+
saveJobsDescriptionsAndLocationToCMS,
|
|
287
|
+
aggregateJobsByFieldToCMS,
|
|
288
|
+
referenceJobsToField,
|
|
289
|
+
createApiKeyCollectionAndFillIt,
|
|
261
290
|
};
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
const { fetch } = require('wix-fetch');
|
|
2
|
+
const { items: wixData } = require('@wix/data');
|
|
3
|
+
const { COLLECTIONS } = require('./collectionConsts');
|
|
2
4
|
|
|
3
|
-
async function makeSmartRecruitersRequest(path) {
|
|
5
|
+
async function makeSmartRecruitersRequest(path,token) {
|
|
4
6
|
// const baseUrl = 'https://api.smartrecruiters.com'; // PROD
|
|
5
7
|
const baseUrl = 'https://aoxley54.wixstudio.com/external-template/_functions'; // TEST
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
const fullUrl = `${baseUrl}${path}`;
|
|
9
|
+
|
|
10
|
+
//console.log(`Making request to: ${fullUrl}`);
|
|
8
11
|
try {
|
|
9
12
|
const response = await fetch(fullUrl, {
|
|
10
13
|
method: 'GET',
|
|
11
14
|
headers: {
|
|
12
15
|
'Accept-Language': 'en',
|
|
13
|
-
accept: 'application/json',
|
|
14
|
-
'x-smarttoken':
|
|
15
|
-
Cookie:
|
|
16
|
-
|
|
17
|
-
},
|
|
16
|
+
'accept': 'application/json',
|
|
17
|
+
'x-smarttoken': token,
|
|
18
|
+
'Cookie': 'AWSALB=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d; AWSALBCORS=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d'
|
|
19
|
+
}
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
if (response.ok) {
|
|
@@ -33,8 +35,9 @@ async function fetchPositionsFromSRAPI() {
|
|
|
33
35
|
let allPositions = [];
|
|
34
36
|
let totalFound = 0;
|
|
35
37
|
let nextPageId = null; // Start with no page ID for the first request
|
|
36
|
-
let
|
|
37
|
-
const MAX_PAGES = 30
|
|
38
|
+
let pageCount = 0;
|
|
39
|
+
const MAX_PAGES = 30 // Safety limit to prevent infinite loops
|
|
40
|
+
const token = await getSmartTokenFromCMS();
|
|
38
41
|
|
|
39
42
|
console.log('Starting to fetch all positions with pagination...');
|
|
40
43
|
|
|
@@ -47,10 +50,10 @@ async function fetchPositionsFromSRAPI() {
|
|
|
47
50
|
if (nextPageId) {
|
|
48
51
|
apiPath += `&nextPageId=${nextPageId}`;
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
console.log(`Fetching page ${
|
|
52
|
-
const response = await makeSmartRecruitersRequest(apiPath);
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
console.log(`Fetching page ${pageCount} with path: ${apiPath}`);
|
|
55
|
+
const response = await makeSmartRecruitersRequest(apiPath,token);
|
|
56
|
+
|
|
54
57
|
// Add positions from this page to our collection
|
|
55
58
|
if (response.content && Array.isArray(response.content)) {
|
|
56
59
|
allPositions = allPositions.concat(response.content);
|
|
@@ -108,6 +111,16 @@ async function fetchJobDescription(jobId) {
|
|
|
108
111
|
return await makeSmartRecruitersRequest(`/jobs/${jobId}`);
|
|
109
112
|
}
|
|
110
113
|
|
|
114
|
+
async function getSmartTokenFromCMS() {
|
|
115
|
+
const result = await wixData.query(COLLECTIONS.API_KEY).limit(1).find();
|
|
116
|
+
if (result.items.length > 0) {
|
|
117
|
+
return result.items[0].token; // This is your string token
|
|
118
|
+
} else {
|
|
119
|
+
return null; // No token found
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
111
124
|
module.exports = {
|
|
112
125
|
fetchPositionsFromSRAPI,
|
|
113
126
|
fetchJobDescription,
|
package/backend/utils.js
CHANGED
|
@@ -26,7 +26,7 @@ function fillCityLocation(jobs, cityLocations) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function
|
|
29
|
+
function prepareToSaveArray(jobsPerField, cityLocations, field) {
|
|
30
30
|
if (field === 'cityText') {
|
|
31
31
|
return Object.entries(jobsPerField).map(([value, amount]) => {
|
|
32
32
|
const loc = cityLocations[value] || {};
|
|
@@ -70,6 +70,6 @@ module.exports = {
|
|
|
70
70
|
delay,
|
|
71
71
|
countJobsPerGivenField,
|
|
72
72
|
fillCityLocation,
|
|
73
|
-
prepateToSaveArray,
|
|
73
|
+
prepateToSaveArray: prepareToSaveArray,
|
|
74
74
|
normalizeCityName,
|
|
75
75
|
};
|