Skip to content

Commit 5c9f0e6

Browse files
Refactor API helper to use API class instead
1 parent 68ed8fe commit 5c9f0e6

File tree

6 files changed

+36
-199
lines changed

6 files changed

+36
-199
lines changed

src/commands/export.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ const {
1212
logAndExit,
1313
testEligibleForExportLog,
1414
} = require("../utils/cmdPrint");
15-
const {
16-
isEligibleForExport,
17-
checkForAPIKey
18-
} = require("../helpers/api");
15+
const {getApiConfig} = require("../helpers/api");
16+
const {API} = require("@pythagora.io/js-code-processing");
1917
const args = require('../utils/getArgs.js');
2018
const {
2119
createDefaultFiles,
@@ -25,7 +23,6 @@ const {
2523
} = require('../helpers/exports');
2624

2725
async function runExport() {
28-
checkForAPIKey();
2926
setUpPythagoraDirs();
3027
cleanupDataFolder();
3128
let exportsMetadata = JSON.parse(fs.readFileSync(path.resolve(args.pythagora_root, PYTHAGORA_METADATA_DIR, EXPORT_METADATA_FILENAME)));
@@ -42,6 +39,9 @@ async function runExport() {
4239
await exportTest(originalTest, exportsMetadata);
4340
}
4441
else {
42+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
43+
const Api = new API(apiUrl, apiKey, apiKeyType);
44+
4545
for (let originalTest of generatedTests) {
4646
if (originalTest.method === 'OPTIONS') continue;
4747
if (testExists(exportsMetadata, originalTest.id)) {
@@ -50,7 +50,7 @@ async function runExport() {
5050
}
5151

5252
let test = convertOldTestForGPT(originalTest);
53-
const isEligible = await isEligibleForExport(test);
53+
const isEligible = await Api.isEligibleForExport(test);
5454

5555
if (isEligible) {
5656
await exportTest(originalTest, exportsMetadata);

src/helpers/api.js

Lines changed: 6 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,174 +1,11 @@
1-
const _ = require('lodash');
2-
const axios = require('axios');
3-
const { jestAuthFileGenerationLog } = require('../utils/cmdPrint');
4-
const { bold, reset, red, blue } = require('../utils/cmdPrint').colors;
51
const args = require('../utils/getArgs.js');
6-
const {PYTHAGORA_UNIT_TESTS_VERSION,PYTHAGORA_API_SERVER} = require("@pythagora.io/js-code-processing").common;
7-
const API_SERVER = args.pythagora_api_server || PYTHAGORA_API_SERVER;
82

9-
function extractGPTMessageFromStreamData(input) {
10-
const regex = /data: (.*?)\n/g;
11-
const substrings = [];
12-
let match;
13-
14-
while ((match = regex.exec(input)) !== null) {
15-
substrings.push(match[1]);
3+
function getApiConfig() {
4+
return {
5+
apiUrl: args.pythagora_api_server || PYTHAGORA_API_SERVER,
6+
apiKey: args.openai_api_key || args.pythagora_api_key,
7+
apiKeyType: args.openai_api_key ? 'openai' : 'pythagora'
168
}
17-
18-
return substrings.map(s => JSON.parse(s));
19-
}
20-
21-
function setOptions({path, method, headers}) {
22-
let apiKey = args.openai_api_key || args.pythagora_api_key;
23-
const parsedUrl = new URL(API_SERVER);
24-
if (!apiKey) throw new Error('No API key provided. Please add --openai-api-key or --pythagora-api-key')
25-
let options = {
26-
protocol: parsedUrl.protocol.replace(':', ''),
27-
hostname: parsedUrl.hostname,
28-
port: parsedUrl.port,
29-
path: path || '/',
30-
method: method || 'POST',
31-
headers: headers || {
32-
'Content-Type': 'application/json',
33-
'apikey': apiKey,
34-
'apikeytype': args.openai_api_key ? 'openai' : 'pythagora'
35-
},
36-
};
37-
38-
if (!options.port) delete options.port;
39-
return options
409
}
4110

42-
async function makeRequest(data, options, customLogFunction) {
43-
let gptResponse = '';
44-
let httpModule = options.protocol === 'http' ? require('http') : require('https');
45-
let timeout;
46-
47-
return new Promise((resolve, reject) => {
48-
const req = httpModule.request(_.omit(options, ['protocol']), function(res){
49-
res.on('data', (chunk) => {
50-
try {
51-
clearTimeout(timeout);
52-
timeout = setTimeout(() => {
53-
reject(new Error("Request timeout"));
54-
}, 30000);
55-
56-
let stringified = chunk.toString();
57-
try {
58-
let json = JSON.parse(stringified);
59-
if (json.error || json.message) {
60-
gptResponse = json;
61-
return;
62-
}
63-
} catch (e) {}
64-
65-
gptResponse += stringified;
66-
if (gptResponse.indexOf('pythagora_end:') > -1) return;
67-
if (customLogFunction) customLogFunction(gptResponse);
68-
else process.stdout.write(stringified);
69-
} catch (e) {}
70-
});
71-
res.on('end', async function () {
72-
clearTimeout(timeout);
73-
74-
process.stdout.write('\n');
75-
if (res.statusCode >= 400) return reject(new Error(`Response status code: ${res.statusCode}. Error message: ${gptResponse}`));
76-
if (gptResponse.error) return reject(new Error(`Error: ${gptResponse.error.message}. Code: ${gptResponse.error.code}`));
77-
if (gptResponse.message) return reject(new Error(`Error: ${gptResponse.message}. Code: ${gptResponse.code}`));
78-
gptResponse = gptResponse.split('pythagora_end:').pop();
79-
return resolve(gptResponse);
80-
});
81-
});
82-
83-
req.on('error', (e) => {
84-
clearTimeout(timeout);
85-
console.error("problem with request:"+e.message);
86-
reject(e);
87-
});
88-
89-
req.write(data);
90-
91-
req.end();
92-
});
93-
}
94-
95-
async function getUnitTests(data, customLogFunction) {
96-
let options = setOptions({path: '/api/generate-unit-tests'});
97-
let tests, error;
98-
try {
99-
tests = await makeRequest(JSON.stringify(data), options, customLogFunction);
100-
} catch (e) {
101-
error = e;
102-
} finally {
103-
return {tests, error};
104-
}
105-
}
106-
107-
async function expandUnitTests(data, customLogFunction) {
108-
let options = setOptions({path: '/api/expand-unit-tests'});
109-
let tests, error;
110-
try {
111-
tests = await makeRequest(JSON.stringify(data), options, customLogFunction);
112-
} catch (e) {
113-
error = e;
114-
} finally {
115-
return {tests, error};
116-
}
117-
}
118-
119-
async function getJestAuthFunction(loginMongoQueriesArray, loginRequestBody, loginEndpointPath) {
120-
jestAuthFileGenerationLog();
121-
122-
let options = setOptions({path: '/api/generate-jest-auth'});
123-
return await makeRequest(JSON.stringify({loginMongoQueriesArray, loginRequestBody, loginEndpointPath}), options);
124-
}
125-
126-
127-
async function getJestTest(test) {
128-
let options = setOptions({path: '/api/generate-jest-test'});
129-
return await makeRequest(JSON.stringify(test), options);
130-
}
131-
132-
async function getJestTestName(test, usedNames) {
133-
let options = setOptions({path:'/api/generate-jest-test-name'});
134-
return await makeRequest(JSON.stringify({ test }), options);
135-
}
136-
137-
async function isEligibleForExport(test) {
138-
try {
139-
let options = setOptions({ path: '/api/check-if-eligible' });
140-
141-
const response = await axios.post(
142-
`${options.protocol}://${options.hostname}${options.port ? ':' + options.port : ''}${options.path}`,
143-
JSON.stringify({ test }),
144-
{ headers: options.headers }
145-
);
146-
147-
return response.data;
148-
} catch (error) {
149-
console.log(error);
150-
return false;
151-
}
152-
}
153-
154-
function checkForAPIKey() {
155-
if (!args.pythagora_api_key && !args.openai_api_key) {
156-
console.log(`${bold+red}No API key found!${reset}`);
157-
console.log('Please run:')
158-
console.log(`${bold+blue}npx pythagora --config --pythagora-api-key <YOUR_PYTHAGORA_API_KEY>${reset}`);
159-
console.log('or')
160-
console.log(`${bold+blue}npx pythagora --config --openai-api-key <YOUR_OPENAI_API_KEY>${reset}`);
161-
console.log(`You can get Pythagora API key here: https://mailchi.mp/f4f4d7270a7a/api-waitlist`);
162-
process.exit(0);
163-
}
164-
}
165-
166-
module.exports = {
167-
getJestAuthFunction,
168-
getJestTest,
169-
getJestTestName,
170-
isEligibleForExport,
171-
getUnitTests,
172-
expandUnitTests,
173-
checkForAPIKey
174-
}
11+
module.exports = {getApiConfig};

src/helpers/exports.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@ const {
1616
enterLoginRouteLog,
1717
testExportStartedLog
1818
} = require("../utils/cmdPrint");
19-
const {
20-
getJestAuthFunction,
21-
getJestTest,
22-
getJestTestName,
23-
cleanupGPTResponse,
24-
} = require("./api");
19+
const {getApiConfig} = require("./api");
2520
const _ = require('lodash');
2621
const args = require('../utils/getArgs.js');
22+
const {API} = require("@pythagora.io/js-code-processing");
2723

2824
async function createDefaultFiles(generatedTests) {
2925
if (!fs.existsSync('jest.config.js')) {
@@ -40,6 +36,9 @@ async function createDefaultFiles(generatedTests) {
4036
}
4137

4238
async function configureAuthFile(generatedTests) {
39+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
40+
const Api = new API(apiUrl, apiKey, apiKeyType);
41+
4342
// TODO make require path better
4443
let pythagoraMetadata = require(`../${SRC_TO_ROOT}.pythagora/${METADATA_FILENAME}`);
4544
let loginPath = _.get(pythagoraMetadata, 'exportRequirements.login.endpointPath');
@@ -64,7 +63,7 @@ async function configureAuthFile(generatedTests) {
6463
}
6564

6665
let loginData = pythagoraMetadata.exportRequirements.login;
67-
let code = await getJestAuthFunction(loginData.mongoQueriesArray, loginData.requestBody, loginData.endpointPath);
66+
let code = await Api.getJestAuthFunction(loginData.mongoQueriesArray, loginData.requestBody, loginData.endpointPath);
6867

6968
fs.writeFileSync(path.resolve(args.pythagora_root, EXPORTED_TESTS_DIR, 'auth.js'), code);
7069
}
@@ -97,10 +96,13 @@ function cleanupDataFolder() {
9796
}
9897

9998
async function exportTest(originalTest, exportsMetadata) {
99+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
100+
const Api = new API(apiUrl, apiKey, apiKeyType);
101+
100102
testExportStartedLog();
101103
let test = convertOldTestForGPT(originalTest);
102-
let jestTest = await getJestTest(test);
103-
let testName = await getJestTestName(jestTest, Object.values(exportsMetadata).map(obj => obj.testName));
104+
let jestTest = await Api.getJestTest(test);
105+
let testName = await Api.getJestTestName(jestTest, Object.values(exportsMetadata).map(obj => obj.testName));
104106
if (!jestTest && !testName) return console.error('There was issue with getting GPT response. Make sure you have access to GPT4 with your API key.');
105107

106108
fs.writeFileSync(`./${EXPORTED_TESTS_DATA_DIR}/${testName.replace('.test.js', '.json')}`, JSON.stringify(test.mongoQueries, null, 2));

src/helpers/unitTests.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
const fs = require('fs');
22
const path = require('path');
3-
const {PYTHAGORA_UNIT_DIR, PYTHAGORA_API_SERVER} = require("@pythagora.io/js-code-processing").common;
3+
const {PYTHAGORA_UNIT_DIR} = require("@pythagora.io/js-code-processing").common;
4+
const {getApiConfig} = require("../helpers/api");
45
const { UnitTests, API } = require("@pythagora.io/js-code-processing");
56
const {initScreenForUnitTests} = require("./cmdGUI");
67
const {green, red, blue, bold, reset} = require('../utils/cmdPrint').colors;
7-
const processArgs = require('../utils/getArgs.js');
88

99
async function generateTestsForDirectory(args) {
10-
const apiUrl = processArgs.pythagora_api_server || PYTHAGORA_API_SERVER;
11-
const apiKey = processArgs.openai_api_key || args.pythagora_api_key;
12-
const apiKeyType = processArgs.openai_api_key ? 'openai' : 'pythagora';
10+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
1311
const Api = new API(apiUrl, apiKey, apiKeyType);
1412

1513
console.log('Processing folder structure...');

src/helpers/unitTestsExpand.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
const fs = require('fs');
22
const path = require('path');
3-
const {PYTHAGORA_UNIT_DIR, PYTHAGORA_API_SERVER} = require("@pythagora.io/js-code-processing").common;
3+
const {PYTHAGORA_UNIT_DIR} = require("@pythagora.io/js-code-processing").common;
4+
const {getApiConfig} = require("../helpers/api");
45
const { UnitTestsExpand, API } = require("@pythagora.io/js-code-processing");
56
const {initScreenForUnitTests} = require("./cmdGUI");
67
const {green, red, blue, bold, reset} = require('../utils/cmdPrint').colors;
7-
const processArgs = require('../utils/getArgs.js');
88

99
async function expandTestsForDirectory(args) {
10-
const apiUrl = processArgs.pythagora_api_server || PYTHAGORA_API_SERVER;
11-
const apiKey = processArgs.openai_api_key || args.pythagora_api_key;
12-
const apiKeyType = processArgs.openai_api_key ? 'openai' : 'pythagora';
10+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
1311
const Api = new API(apiUrl, apiKey, apiKeyType);
1412

1513
console.log('Processing folder structure...');

src/scripts/testsEligibleForExport.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@ const path = require("path");
33
const {getAllGeneratedTests} = require("../utils/common");
44
const {convertOldTestForGPT} = require("../utils/legacy");
55
const {testEligibleForExportLog} = require("../utils/cmdPrint");
6-
const {isEligibleForExport} = require("../helpers/api");
6+
const {getApiConfig} = require("../helpers/api");
7+
const {API} = require("@pythagora.io/js-code-processing");
78
const args = require("../utils/getArgs");
8-
const { UnitTestsCommon } = require("@pythagora.io/js-code-processing");
9+
const {UnitTestsCommon} = require("@pythagora.io/js-code-processing");
910

1011

1112
async function testsEligibleForExport() {
13+
const { apiUrl, apiKey, apiKeyType } = getApiConfig();
14+
const Api = new API(apiUrl, apiKey, apiKeyType);
15+
1216
let csvData = 'endpoint,testId,tokens\n';
1317
let tests = getAllGeneratedTests();
1418
for (let test of tests) {
1519
test = convertOldTestForGPT(test);
16-
let isEligible = await isEligibleForExport(test);
20+
let isEligible = await Api.isEligibleForExport(test);
1721
testEligibleForExportLog(test.endpoint, test.testId, isEligible);
1822
csvData += `${test.endpoint},${test.testId},${isEligible ? 'TRUE' : 'FALSE'}\n`;
1923
}
@@ -25,8 +29,6 @@ async function testsEligibleForExport() {
2529
}
2630

2731
async function unitTestsEligibleForExport() {
28-
const { UnitTestsCommon } = require("@pythagora.io/js-code-processing");
29-
3032
const unitTestsCommon = new UnitTestsCommon({
3133
pathToProcess: args.path,
3234
pythagoraRoot: args.pythagora_root

0 commit comments

Comments
 (0)