diffpx 0.0.3 → 0.0.5
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/bin/diffpx.js +5 -6
- package/package.json +1 -1
- package/src/configLoader.js +3 -3
- package/src/runner.js +19 -13
- package/src/upload.js +12 -14
- package/src/validateConfig.js +8 -9
package/bin/diffpx.js
CHANGED
|
@@ -4,10 +4,7 @@ const {loadConfig} = require('../src/configLoader');
|
|
|
4
4
|
const {runJob} = require('../src/runner');
|
|
5
5
|
|
|
6
6
|
(async () => {
|
|
7
|
-
const {config, devicesConfig, settings} = await loadConfig();
|
|
8
|
-
|
|
9
|
-
const ppKey = process.env.PP_KEY;
|
|
10
|
-
if (!ppKey) throw new Error('No API key found in .env or settings.yml');
|
|
7
|
+
const {config, devicesConfig, settings, diffpxKey, diffpxUrl} = await loadConfig();
|
|
11
8
|
|
|
12
9
|
const timestamp = new Date().toISOString().replace('T', ' ').split('.')[0];
|
|
13
10
|
const groupId = crypto.randomUUID();
|
|
@@ -15,14 +12,16 @@ const {runJob} = require('../src/runner');
|
|
|
15
12
|
const payload = {
|
|
16
13
|
timestamp,
|
|
17
14
|
groupId,
|
|
18
|
-
settings
|
|
15
|
+
settings: {
|
|
16
|
+
...settings
|
|
17
|
+
},
|
|
19
18
|
devices: devicesConfig,
|
|
20
19
|
snapshots: config
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
try {
|
|
24
23
|
await runJob({
|
|
25
|
-
|
|
24
|
+
diffpxKey,
|
|
26
25
|
payload
|
|
27
26
|
});
|
|
28
27
|
} catch (err) {
|
package/package.json
CHANGED
package/src/configLoader.js
CHANGED
|
@@ -3,9 +3,9 @@ const yaml = require('js-yaml');
|
|
|
3
3
|
const validateConfig = require('./validateConfig');
|
|
4
4
|
|
|
5
5
|
async function loadConfig() {
|
|
6
|
-
const { config, devicesConfig } = await validateConfig();
|
|
7
|
-
const settings = yaml.load(fs.readFileSync('settings.yml', 'utf8'));
|
|
8
|
-
return { config, devicesConfig, settings };
|
|
6
|
+
const { config, devicesConfig, diffpxKey, diffpxUrl } = await validateConfig();
|
|
7
|
+
const settings = yaml.load(fs.readFileSync('settings.yml', 'utf8')) || {};
|
|
8
|
+
return { config, devicesConfig, settings, diffpxKey, diffpxUrl };
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
module.exports = { loadConfig };
|
package/src/runner.js
CHANGED
|
@@ -45,18 +45,20 @@ function getProgress(status) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
async function runJob({
|
|
48
|
+
async function runJob({diffpxKey, payload}) {
|
|
49
|
+
const initialSnapshotsTotal = Array.isArray(payload?.snapshots) ? payload.snapshots.length : 1;
|
|
50
|
+
const initialWidthsTotal = Array.isArray(payload?.settings?.width) ? payload.settings.width.length : 1;
|
|
51
|
+
const isTTY = !!process.stdout.isTTY;
|
|
49
52
|
const multiBar = new cliProgress.MultiBar({
|
|
50
53
|
clearOnComplete: false,
|
|
51
54
|
hideCursor: true,
|
|
52
55
|
barCompleteChar: '█',
|
|
53
56
|
barIncompleteChar: '░',
|
|
54
|
-
format: '{name} [{bar}] {percentage}% | {value}/{total}'
|
|
57
|
+
format: '{name} [{bar}] {percentage}% | {value}/{total}',
|
|
58
|
+
noTTYOutput: !isTTY,
|
|
59
|
+
notTTYSchedule: 1000
|
|
55
60
|
}, cliProgress.Presets.shades_classic);
|
|
56
61
|
|
|
57
|
-
const initialSnapshotsTotal = Array.isArray(payload?.snapshots) ? payload.snapshots.length : 1;
|
|
58
|
-
const initialWidthsTotal = Array.isArray(payload?.settings?.width) ? payload.settings.width.length : 1;
|
|
59
|
-
|
|
60
62
|
const snapshotsBar = multiBar.create(
|
|
61
63
|
Math.max(1, initialSnapshotsTotal),
|
|
62
64
|
0,
|
|
@@ -72,14 +74,15 @@ async function runJob({ppKey, payload}) {
|
|
|
72
74
|
let jobId = null;
|
|
73
75
|
|
|
74
76
|
try {
|
|
75
|
-
const
|
|
77
|
+
const diffpxUrl = process.env.DIFFPX_URL || '';
|
|
78
|
+
const res = await submitRun(diffpxUrl, diffpxKey, payload);
|
|
76
79
|
jobId = res?.jobId || res?.id || res?.job_id || res?.data?.jobId || null;
|
|
77
80
|
if (!jobId) {
|
|
78
81
|
throw new Error('Server did not return a job id');
|
|
79
82
|
}
|
|
80
83
|
|
|
81
|
-
const finalStatus = await pollRun(
|
|
82
|
-
intervalMs: Number(process.env.
|
|
84
|
+
const finalStatus = await pollRun(diffpxUrl, diffpxKey, jobId, {
|
|
85
|
+
intervalMs: Number(process.env.DIFFPX_POLL_INTERVAL_MS || 1000),
|
|
83
86
|
onStatus: (status) => {
|
|
84
87
|
const p = getProgress(status);
|
|
85
88
|
|
|
@@ -87,14 +90,17 @@ async function runJob({ppKey, payload}) {
|
|
|
87
90
|
const widthLabel = normalizePxLabel(p.widthLabel) || getInitialWidthName(payload);
|
|
88
91
|
|
|
89
92
|
const snapTotal = p.snapshotsTotal > 0 ? p.snapshotsTotal : Math.max(1, initialSnapshotsTotal);
|
|
90
|
-
const snapDone = p.snapshotsTotal > 0
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
snapshotsBar.update(snapDone, {name: snapshotLabel});
|
|
93
|
+
const snapDone = p.snapshotsTotal > 0
|
|
94
|
+
? Math.min(p.snapshotsDone, p.snapshotsTotal)
|
|
95
|
+
: (snapshotsBar ? snapshotsBar.value : 0);
|
|
94
96
|
|
|
95
97
|
const wTotal = p.widthsTotal > 0 ? p.widthsTotal : Math.max(1, initialWidthsTotal);
|
|
96
|
-
const wDone = p.widthsTotal > 0
|
|
98
|
+
const wDone = p.widthsTotal > 0
|
|
99
|
+
? Math.min(p.widthsDone, p.widthsTotal)
|
|
100
|
+
: widthsBar.value;
|
|
97
101
|
|
|
102
|
+
snapshotsBar.setTotal(snapTotal);
|
|
103
|
+
snapshotsBar.update(snapDone, {name: snapshotLabel});
|
|
98
104
|
widthsBar.setTotal(wTotal);
|
|
99
105
|
widthsBar.update(wDone, {name: widthLabel});
|
|
100
106
|
}
|
package/src/upload.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
require('dotenv').config({ path: require('path').join(process.cwd(), '.env') });
|
|
3
3
|
|
|
4
|
-
const ppUrl = process.env.PP_URL || '';
|
|
5
|
-
|
|
6
4
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
7
5
|
|
|
8
6
|
function axiosErrorMessage(err) {
|
|
@@ -19,16 +17,16 @@ function axiosErrorMessage(err) {
|
|
|
19
17
|
.join(' | ');
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
async function submitRun(
|
|
23
|
-
if (!
|
|
24
|
-
throw new Error('
|
|
20
|
+
async function submitRun(diffpxUrl, diffpxKey, payload) {
|
|
21
|
+
if (!diffpxUrl) {
|
|
22
|
+
throw new Error('DIFFPX_URL not configured');
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
try {
|
|
28
|
-
const res = await axios.post(`${
|
|
26
|
+
const res = await axios.post(`${diffpxUrl}/runs`, payload, {
|
|
29
27
|
headers: {
|
|
30
28
|
'Content-Type': 'application/json',
|
|
31
|
-
Authorization: `Bearer ${
|
|
29
|
+
Authorization: `Bearer ${diffpxKey}`
|
|
32
30
|
},
|
|
33
31
|
maxBodyLength: Infinity
|
|
34
32
|
});
|
|
@@ -39,15 +37,15 @@ async function submitRun(ppKey, payload) {
|
|
|
39
37
|
}
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
async function fetchJobStatus(
|
|
43
|
-
if (!
|
|
44
|
-
throw new Error('
|
|
40
|
+
async function fetchJobStatus(diffpxUrl, diffpxKey, jobId) {
|
|
41
|
+
if (!diffpxUrl) {
|
|
42
|
+
throw new Error('DIFFPX_URL not configured');
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
try {
|
|
48
|
-
const res = await axios.get(`${
|
|
46
|
+
const res = await axios.get(`${diffpxUrl}/runs/${encodeURIComponent(jobId)}`, {
|
|
49
47
|
headers: {
|
|
50
|
-
Authorization: `Bearer ${
|
|
48
|
+
Authorization: `Bearer ${diffpxKey}`
|
|
51
49
|
}
|
|
52
50
|
});
|
|
53
51
|
|
|
@@ -57,9 +55,9 @@ async function fetchJobStatus(ppKey, jobId) {
|
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
async function pollRun(
|
|
58
|
+
async function pollRun(diffpxUrl, diffpxKey, jobId, {intervalMs = 1000, onStatus} = {}) {
|
|
61
59
|
for (;;) {
|
|
62
|
-
const status = await fetchJobStatus(
|
|
60
|
+
const status = await fetchJobStatus(diffpxUrl, diffpxKey, jobId);
|
|
63
61
|
if (onStatus) onStatus(status);
|
|
64
62
|
|
|
65
63
|
const state = String(status?.state || status?.status || '').toLowerCase();
|
package/src/validateConfig.js
CHANGED
|
@@ -5,12 +5,11 @@ require('dotenv').config({ path: require('path').join(process.cwd(), '.env') });
|
|
|
5
5
|
|
|
6
6
|
async function validateConfig() {
|
|
7
7
|
const errors = [];
|
|
8
|
+
const diffpxKey = process.env.DIFFPX_KEY;
|
|
9
|
+
const diffpxUrl = process.env.DIFFPX_URL;
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!ppKey) errors.push("🔴 Missing PP_KEY in .env");
|
|
13
|
-
if (!ppUrl) errors.push("🔴 Missing PP_URL in .env");
|
|
11
|
+
if (!diffpxKey) errors.push("🔴 Missing DIFFPX_KEY (set in .env or CI vars)");
|
|
12
|
+
if (!diffpxUrl) errors.push("🔴 Missing DIFFPX_URL (set in .env or CI vars)");
|
|
14
13
|
|
|
15
14
|
if (errors.length > 0) {
|
|
16
15
|
console.error("🔴 Configuration check failed:");
|
|
@@ -19,14 +18,14 @@ async function validateConfig() {
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
try {
|
|
22
|
-
await axios.get(`${
|
|
23
|
-
headers: { Authorization: `Bearer ${
|
|
21
|
+
await axios.get(`${ diffpxUrl }/auth/ping`, {
|
|
22
|
+
headers: { Authorization: `Bearer ${ diffpxKey }` },
|
|
24
23
|
timeout: 5000
|
|
25
24
|
});
|
|
26
25
|
} catch (err) {
|
|
27
26
|
const msg = err.response?.data?.error || err.message;
|
|
28
27
|
if (String(msg).includes("ECONNREFUSED") || String(msg).includes("ENOTFOUND")) {
|
|
29
|
-
console.error("🔴 API validation failed: Connection to server failed. Make sure
|
|
28
|
+
console.error("🔴 API validation failed: Connection to server failed. Make sure DIFFPX_URL is correct");
|
|
30
29
|
} else {
|
|
31
30
|
console.error("🔴 API validation failed:", msg);
|
|
32
31
|
}
|
|
@@ -66,7 +65,7 @@ async function validateConfig() {
|
|
|
66
65
|
console.log("🟢 Configuration check passed.");
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
return { config, devicesConfig };
|
|
68
|
+
return { config, devicesConfig, diffpxKey, diffpxUrl };
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
module.exports = validateConfig;
|