alurkerja-cli 1.0.3 → 1.0.4

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 (3) hide show
  1. package/index.js +57 -55
  2. package/index.js.backup +57 -55
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -69,54 +69,59 @@ async function downloadBinary(version, platform) {
69
69
 
70
70
  return new Promise((resolve, reject) => {
71
71
  const file = fs.createWriteStream(tempPath);
72
+ let downloadComplete = false;
72
73
 
73
- const url = new URL(downloadUrl);
74
- const options = {
75
- hostname: url.hostname,
76
- path: url.pathname + url.search,
77
- headers: {
78
- 'PRIVATE-TOKEN': GITLAB_TOKEN
79
- }
80
- };
81
-
82
- const req = https.get(options, (res) => {
83
- if (res.statusCode === 302 || res.statusCode === 301) {
84
- // Follow redirect with token
85
- const redirectUrl = new URL(res.headers.location);
86
- const redirectOptions = {
87
- hostname: redirectUrl.hostname,
88
- path: redirectUrl.pathname + redirectUrl.search,
89
- headers: {
90
- 'PRIVATE-TOKEN': GITLAB_TOKEN
91
- }
92
- };
93
- return https.get(redirectOptions, (redirectRes) => {
94
- redirectRes.pipe(file);
74
+ const downloadFile = (targetUrl) => {
75
+ const url = new URL(targetUrl);
76
+ const options = {
77
+ hostname: url.hostname,
78
+ path: url.pathname + url.search,
79
+ headers: {
80
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
81
+ }
82
+ };
83
+
84
+ const req = https.get(options, (res) => {
85
+ if (res.statusCode === 302 || res.statusCode === 301) {
86
+ // Follow redirect
87
+ const redirectUrl = res.headers.location.startsWith('http')
88
+ ? res.headers.location
89
+ : `https://${url.hostname}${res.headers.location}`;
90
+ return downloadFile(redirectUrl);
91
+ }
92
+
93
+ if (res.statusCode !== 200) {
94
+ file.close();
95
+ try { fs.unlinkSync(tempPath); } catch {}
96
+ reject(new Error(`Download failed with status ${res.statusCode}`));
97
+ return;
98
+ }
99
+
100
+ res.pipe(file);
101
+ res.on('end', () => {
102
+ downloadComplete = true;
95
103
  });
96
- }
104
+ });
97
105
 
98
- if (res.statusCode !== 200) {
99
- file.close();
100
- fs.unlinkSync(tempPath);
101
- reject(new Error(`Download failed with status ${res.statusCode}`));
102
- return;
103
- }
106
+ req.on('error', (err) => {
107
+ if (!downloadComplete) {
108
+ file.close();
109
+ try { fs.unlinkSync(tempPath); } catch {}
110
+ reject(err);
111
+ }
112
+ });
104
113
 
105
- res.pipe(file);
106
- });
107
-
108
- req.on('error', (err) => {
109
- file.close();
110
- try { fs.unlinkSync(tempPath); } catch {}
111
- reject(err);
112
- });
114
+ req.setTimeout(30000, () => {
115
+ if (!downloadComplete) {
116
+ req.abort();
117
+ file.close();
118
+ try { fs.unlinkSync(tempPath); } catch {}
119
+ reject(new Error('Download timeout'));
120
+ }
121
+ });
122
+ };
113
123
 
114
- req.setTimeout(30000, () => {
115
- req.abort();
116
- file.close();
117
- try { fs.unlinkSync(tempPath); } catch {}
118
- reject(new Error('Download timeout'));
119
- });
124
+ downloadFile(downloadUrl);
120
125
 
121
126
  file.on('error', (err) => {
122
127
  try { fs.unlinkSync(tempPath); } catch {}
@@ -131,7 +136,15 @@ async function downloadBinary(version, platform) {
131
136
  return;
132
137
  }
133
138
 
134
- // Make executable on Unix systems before renaming
139
+ // Validate the downloaded file
140
+ const stats = fs.statSync(tempPath);
141
+ if (stats.size < 1000) {
142
+ try { fs.unlinkSync(tempPath); } catch {}
143
+ reject(new Error(`Download failed: received invalid file (${stats.size} bytes)`));
144
+ return;
145
+ }
146
+
147
+ // Make executable on Unix systems
135
148
  if (platform.os !== 'windows') {
136
149
  try {
137
150
  fs.chmodSync(tempPath, '755');
@@ -142,19 +155,8 @@ async function downloadBinary(version, platform) {
142
155
  }
143
156
  }
144
157
 
145
- // Validate the downloaded file
146
- const stats = fs.statSync(tempPath);
147
- if (stats.size < 1000) {
148
- // File too small, likely an error page
149
- const content = fs.readFileSync(tempPath, 'utf8');
150
- try { fs.unlinkSync(tempPath); } catch {}
151
- reject(new Error(`Download failed: received invalid file (${stats.size} bytes)`));
152
- return;
153
- }
154
-
155
158
  // Rename temp file to final path
156
159
  try {
157
- // Remove old binary if exists
158
160
  if (fs.existsSync(BINARY_PATH)) {
159
161
  fs.unlinkSync(BINARY_PATH);
160
162
  }
package/index.js.backup CHANGED
@@ -69,54 +69,59 @@ async function downloadBinary(version, platform) {
69
69
 
70
70
  return new Promise((resolve, reject) => {
71
71
  const file = fs.createWriteStream(tempPath);
72
+ let downloadComplete = false;
72
73
 
73
- const url = new URL(downloadUrl);
74
- const options = {
75
- hostname: url.hostname,
76
- path: url.pathname + url.search,
77
- headers: {
78
- 'PRIVATE-TOKEN': GITLAB_TOKEN
79
- }
80
- };
81
-
82
- const req = https.get(options, (res) => {
83
- if (res.statusCode === 302 || res.statusCode === 301) {
84
- // Follow redirect with token
85
- const redirectUrl = new URL(res.headers.location);
86
- const redirectOptions = {
87
- hostname: redirectUrl.hostname,
88
- path: redirectUrl.pathname + redirectUrl.search,
89
- headers: {
90
- 'PRIVATE-TOKEN': GITLAB_TOKEN
91
- }
92
- };
93
- return https.get(redirectOptions, (redirectRes) => {
94
- redirectRes.pipe(file);
74
+ const downloadFile = (targetUrl) => {
75
+ const url = new URL(targetUrl);
76
+ const options = {
77
+ hostname: url.hostname,
78
+ path: url.pathname + url.search,
79
+ headers: {
80
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
81
+ }
82
+ };
83
+
84
+ const req = https.get(options, (res) => {
85
+ if (res.statusCode === 302 || res.statusCode === 301) {
86
+ // Follow redirect
87
+ const redirectUrl = res.headers.location.startsWith('http')
88
+ ? res.headers.location
89
+ : `https://${url.hostname}${res.headers.location}`;
90
+ return downloadFile(redirectUrl);
91
+ }
92
+
93
+ if (res.statusCode !== 200) {
94
+ file.close();
95
+ try { fs.unlinkSync(tempPath); } catch {}
96
+ reject(new Error(`Download failed with status ${res.statusCode}`));
97
+ return;
98
+ }
99
+
100
+ res.pipe(file);
101
+ res.on('end', () => {
102
+ downloadComplete = true;
95
103
  });
96
- }
104
+ });
97
105
 
98
- if (res.statusCode !== 200) {
99
- file.close();
100
- fs.unlinkSync(tempPath);
101
- reject(new Error(`Download failed with status ${res.statusCode}`));
102
- return;
103
- }
106
+ req.on('error', (err) => {
107
+ if (!downloadComplete) {
108
+ file.close();
109
+ try { fs.unlinkSync(tempPath); } catch {}
110
+ reject(err);
111
+ }
112
+ });
104
113
 
105
- res.pipe(file);
106
- });
107
-
108
- req.on('error', (err) => {
109
- file.close();
110
- try { fs.unlinkSync(tempPath); } catch {}
111
- reject(err);
112
- });
114
+ req.setTimeout(30000, () => {
115
+ if (!downloadComplete) {
116
+ req.abort();
117
+ file.close();
118
+ try { fs.unlinkSync(tempPath); } catch {}
119
+ reject(new Error('Download timeout'));
120
+ }
121
+ });
122
+ };
113
123
 
114
- req.setTimeout(30000, () => {
115
- req.abort();
116
- file.close();
117
- try { fs.unlinkSync(tempPath); } catch {}
118
- reject(new Error('Download timeout'));
119
- });
124
+ downloadFile(downloadUrl);
120
125
 
121
126
  file.on('error', (err) => {
122
127
  try { fs.unlinkSync(tempPath); } catch {}
@@ -131,7 +136,15 @@ async function downloadBinary(version, platform) {
131
136
  return;
132
137
  }
133
138
 
134
- // Make executable on Unix systems before renaming
139
+ // Validate the downloaded file
140
+ const stats = fs.statSync(tempPath);
141
+ if (stats.size < 1000) {
142
+ try { fs.unlinkSync(tempPath); } catch {}
143
+ reject(new Error(`Download failed: received invalid file (${stats.size} bytes)`));
144
+ return;
145
+ }
146
+
147
+ // Make executable on Unix systems
135
148
  if (platform.os !== 'windows') {
136
149
  try {
137
150
  fs.chmodSync(tempPath, '755');
@@ -142,19 +155,8 @@ async function downloadBinary(version, platform) {
142
155
  }
143
156
  }
144
157
 
145
- // Validate the downloaded file
146
- const stats = fs.statSync(tempPath);
147
- if (stats.size < 1000) {
148
- // File too small, likely an error page
149
- const content = fs.readFileSync(tempPath, 'utf8');
150
- try { fs.unlinkSync(tempPath); } catch {}
151
- reject(new Error(`Download failed: received invalid file (${stats.size} bytes)`));
152
- return;
153
- }
154
-
155
158
  // Rename temp file to final path
156
159
  try {
157
- // Remove old binary if exists
158
160
  if (fs.existsSync(BINARY_PATH)) {
159
161
  fs.unlinkSync(BINARY_PATH);
160
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alurkerja-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Alurkerja CLI - npx wrapper for Go binary",
5
5
  "main": "index.js",
6
6
  "private": false,