sr-npm 1.7.54 → 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 -11
- 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,5 +1,9 @@
|
|
|
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
|
|
|
@@ -27,8 +31,6 @@ async function saveJobsDataToCMS() {
|
|
|
27
31
|
const chunkSize = 1000;
|
|
28
32
|
let totalSaved = 0;
|
|
29
33
|
const totalChunks = Math.ceil(jobsData.length / chunkSize);
|
|
30
|
-
console.log('jobsData is ', jobsData);
|
|
31
|
-
console.log('totalChunks is ', totalChunks);
|
|
32
34
|
|
|
33
35
|
console.log(
|
|
34
36
|
`Processing ${jobsData.length} jobs in ${totalChunks} chunks of max ${chunkSize} items each`
|
|
@@ -138,20 +140,20 @@ async function saveJobsDescriptionsAndLocationToCMS() {
|
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
|
|
141
|
-
|
|
143
|
+
function iterateOverAllJobs(results, field) {
|
|
144
|
+
const jobsPerField = {};
|
|
145
|
+
const cityLocations = {};
|
|
142
146
|
countJobsPerGivenField(results, field, jobsPerField);
|
|
143
147
|
if (field === 'cityText') {
|
|
144
148
|
fillCityLocation(results, cityLocations);
|
|
145
149
|
}
|
|
146
|
-
|
|
150
|
+
return { jobsPerField, cityLocations };
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
async function aggregateJobsByFieldToCMS({ field, collection }) {
|
|
150
154
|
console.log(`counting jobs per ${field}.`);
|
|
151
|
-
const jobsPerField = {};
|
|
152
|
-
const cityLocations = {};
|
|
153
155
|
let results = await getAllPositions();
|
|
154
|
-
|
|
156
|
+
const { jobsPerField, cityLocations } = iterateOverAllJobs(results, field);
|
|
155
157
|
const toSave = prepateToSaveArray(jobsPerField, cityLocations, field);
|
|
156
158
|
if (toSave.length === 0) {
|
|
157
159
|
console.log('No jobs found.');
|
|
@@ -250,9 +252,39 @@ function fetchJobLocation(jobDetails) {
|
|
|
250
252
|
return jobLocation;
|
|
251
253
|
}
|
|
252
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
|
+
|
|
253
284
|
module.exports = {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
285
|
+
saveJobsDataToCMS,
|
|
286
|
+
saveJobsDescriptionsAndLocationToCMS,
|
|
287
|
+
aggregateJobsByFieldToCMS,
|
|
288
|
+
referenceJobsToField,
|
|
289
|
+
createApiKeyCollectionAndFillIt,
|
|
258
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
|
};
|