alurkerja-cli 1.0.0 → 1.0.2

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/index.js CHANGED
@@ -13,7 +13,8 @@ const https = require('https');
13
13
  const { execSync, spawn } = require('child_process');
14
14
  const os = require('os');
15
15
 
16
- const REPO = 'alurkerja/alurkerja-cli';
16
+ const GITLAB_BASE = 'https://gitlab.javan.co.id/alurkerja/on-premises/toolkits/alurkerja-cli';
17
+ const GITLAB_TOKEN = 'javan-_P_JrtswtvrZekJDk1Lt'; // GitLab private token
17
18
  const VERSION = 'v1.0.0'; // Will be replaced during build
18
19
  const INSTALL_DIR = path.join(os.homedir(), '.alurkerja', 'bin');
19
20
  const BINARY_PATH = path.join(INSTALL_DIR, 'alurkerja');
@@ -44,87 +45,115 @@ function detectPlatform() {
44
45
  }
45
46
 
46
47
  /**
47
- * Get the latest version from GitHub if VERSION is 'latest'
48
+ * Get the version to download
48
49
  */
49
- async function getLatestVersion() {
50
- if (VERSION !== 'latest' && VERSION !== 'v1.0.0.') {
51
- return VERSION;
52
- }
53
-
54
- return new Promise((resolve, reject) => {
55
- const options = {
56
- hostname: 'api.github.com',
57
- path: `/repos/${REPO}/releases/latest`,
58
- headers: { 'User-Agent': 'alurkerja-cli-wrapper' }
59
- };
60
-
61
- const req = https.get(options, (res) => {
62
- let data = '';
63
- res.on('data', chunk => data += chunk);
64
- res.on('end', () => {
65
- try {
66
- const release = JSON.parse(data);
67
- resolve(release.tag_name);
68
- } catch (err) {
69
- reject(new Error('Failed to parse GitHub API response'));
70
- }
71
- });
72
- });
73
-
74
- req.on('error', reject);
75
- req.setTimeout(10000, () => {
76
- req.abort();
77
- reject(new Error('GitHub API request timeout'));
78
- });
79
- });
50
+ function getVersion() {
51
+ return VERSION;
80
52
  }
81
53
 
82
54
  /**
83
- * Download binary from GitHub releases
55
+ * Download binary from GitLab releases
84
56
  */
85
57
  async function downloadBinary(version, platform) {
86
58
  const binaryName = `alurkerja-${platform.os}-${platform.arch}${platform.os === 'windows' ? '.exe' : ''}`;
87
- const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${binaryName}`;
59
+ const downloadUrl = `${GITLAB_BASE}/-/raw/master/dist/${binaryName}`;
88
60
 
89
61
  console.log(`📥 Downloading Alurkerja CLI ${version}...`);
90
62
 
91
63
  // Ensure install directory exists
92
64
  fs.mkdirSync(INSTALL_DIR, { recursive: true });
93
65
 
66
+ // Use temporary file to avoid ETXTBSY error
67
+ const tempPath = `${BINARY_PATH}.tmp`;
68
+
94
69
  return new Promise((resolve, reject) => {
95
- const file = fs.createWriteStream(BINARY_PATH);
70
+ const file = fs.createWriteStream(tempPath);
71
+
72
+ const url = new URL(downloadUrl);
73
+ const options = {
74
+ hostname: url.hostname,
75
+ path: url.pathname + url.search,
76
+ headers: {
77
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
78
+ }
79
+ };
96
80
 
97
- const req = https.get(downloadUrl, (res) => {
81
+ const req = https.get(options, (res) => {
98
82
  if (res.statusCode === 302 || res.statusCode === 301) {
99
- // Follow redirect
100
- return https.get(res.headers.location, (redirectRes) => {
83
+ // Follow redirect with token
84
+ const redirectUrl = new URL(res.headers.location);
85
+ const redirectOptions = {
86
+ hostname: redirectUrl.hostname,
87
+ path: redirectUrl.pathname + redirectUrl.search,
88
+ headers: {
89
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
90
+ }
91
+ };
92
+ return https.get(redirectOptions, (redirectRes) => {
101
93
  redirectRes.pipe(file);
102
- redirectRes.on('end', resolve);
103
94
  });
104
95
  }
105
96
 
106
97
  if (res.statusCode !== 200) {
98
+ file.close();
99
+ fs.unlinkSync(tempPath);
107
100
  reject(new Error(`Download failed with status ${res.statusCode}`));
108
101
  return;
109
102
  }
110
103
 
111
104
  res.pipe(file);
112
- res.on('end', resolve);
113
105
  });
114
106
 
115
- req.on('error', reject);
107
+ req.on('error', (err) => {
108
+ file.close();
109
+ try { fs.unlinkSync(tempPath); } catch {}
110
+ reject(err);
111
+ });
112
+
116
113
  req.setTimeout(30000, () => {
117
114
  req.abort();
115
+ file.close();
116
+ try { fs.unlinkSync(tempPath); } catch {}
118
117
  reject(new Error('Download timeout'));
119
118
  });
120
119
 
121
- file.on('error', reject);
120
+ file.on('error', (err) => {
121
+ try { fs.unlinkSync(tempPath); } catch {}
122
+ reject(err);
123
+ });
124
+
122
125
  file.on('finish', () => {
123
- file.close();
124
- // Make executable on Unix systems
125
- if (platform.os !== 'windows') {
126
- fs.chmodSync(BINARY_PATH, '755');
127
- }
126
+ file.close((err) => {
127
+ if (err) {
128
+ try { fs.unlinkSync(tempPath); } catch {}
129
+ reject(err);
130
+ return;
131
+ }
132
+
133
+ // Make executable on Unix systems before renaming
134
+ if (platform.os !== 'windows') {
135
+ try {
136
+ fs.chmodSync(tempPath, '755');
137
+ } catch (err) {
138
+ try { fs.unlinkSync(tempPath); } catch {}
139
+ reject(new Error(`Failed to make binary executable: ${err.message}`));
140
+ return;
141
+ }
142
+ }
143
+
144
+ // Rename temp file to final path
145
+ try {
146
+ // Remove old binary if exists
147
+ if (fs.existsSync(BINARY_PATH)) {
148
+ fs.unlinkSync(BINARY_PATH);
149
+ }
150
+ fs.renameSync(tempPath, BINARY_PATH);
151
+ resolve();
152
+ } catch (err) {
153
+ try { fs.unlinkSync(tempPath); } catch {}
154
+ reject(new Error(`Failed to install binary: ${err.message}`));
155
+ }
156
+ });
128
157
  });
129
158
  });
130
159
  }
@@ -179,16 +208,16 @@ function executeBinary(args) {
179
208
  async function bootstrap() {
180
209
  try {
181
210
  const platform = detectPlatform();
182
- const latestVersion = await getLatestVersion();
211
+ const version = getVersion();
183
212
  const installedVersion = getInstalledVersion();
184
213
 
185
214
  // Check if we need to download the binary
186
215
  const needsDownload = !binaryExists() ||
187
- (installedVersion !== latestVersion && latestVersion !== 'dev');
216
+ (installedVersion !== version && version !== 'dev');
188
217
 
189
218
  if (needsDownload) {
190
- await downloadBinary(latestVersion, platform);
191
- console.log(`✅ Alurkerja CLI ${latestVersion} ready!`);
219
+ await downloadBinary(version, platform);
220
+ console.log(`✅ Alurkerja CLI ${version} ready!`);
192
221
  }
193
222
 
194
223
  // Execute the binary with all arguments passed to this script
package/index.js.backup CHANGED
@@ -13,8 +13,9 @@ const https = require('https');
13
13
  const { execSync, spawn } = require('child_process');
14
14
  const os = require('os');
15
15
 
16
- const REPO = 'alurkerja/alurkerja-cli';
17
- const VERSION = 'VERSION_PLACEHOLDER'; // Will be replaced during build
16
+ const GITLAB_BASE = 'https://gitlab.javan.co.id/alurkerja/on-premises/toolkits/alurkerja-cli';
17
+ const GITLAB_TOKEN = 'javan-_P_JrtswtvrZekJDk1Lt'; // GitLab private token
18
+ const VERSION = 'v1.0.0'; // Will be replaced during build
18
19
  const INSTALL_DIR = path.join(os.homedir(), '.alurkerja', 'bin');
19
20
  const BINARY_PATH = path.join(INSTALL_DIR, 'alurkerja');
20
21
 
@@ -44,87 +45,115 @@ function detectPlatform() {
44
45
  }
45
46
 
46
47
  /**
47
- * Get the latest version from GitHub if VERSION is 'latest'
48
+ * Get the version to download
48
49
  */
49
- async function getLatestVersion() {
50
- if (VERSION !== 'latest' && VERSION !== 'v1.0.0.') {
51
- return VERSION;
52
- }
53
-
54
- return new Promise((resolve, reject) => {
55
- const options = {
56
- hostname: 'api.github.com',
57
- path: `/repos/${REPO}/releases/latest`,
58
- headers: { 'User-Agent': 'alurkerja-cli-wrapper' }
59
- };
60
-
61
- const req = https.get(options, (res) => {
62
- let data = '';
63
- res.on('data', chunk => data += chunk);
64
- res.on('end', () => {
65
- try {
66
- const release = JSON.parse(data);
67
- resolve(release.tag_name);
68
- } catch (err) {
69
- reject(new Error('Failed to parse GitHub API response'));
70
- }
71
- });
72
- });
73
-
74
- req.on('error', reject);
75
- req.setTimeout(10000, () => {
76
- req.abort();
77
- reject(new Error('GitHub API request timeout'));
78
- });
79
- });
50
+ function getVersion() {
51
+ return VERSION;
80
52
  }
81
53
 
82
54
  /**
83
- * Download binary from GitHub releases
55
+ * Download binary from GitLab releases
84
56
  */
85
57
  async function downloadBinary(version, platform) {
86
58
  const binaryName = `alurkerja-${platform.os}-${platform.arch}${platform.os === 'windows' ? '.exe' : ''}`;
87
- const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${binaryName}`;
59
+ const downloadUrl = `${GITLAB_BASE}/-/raw/master/dist/${binaryName}`;
88
60
 
89
61
  console.log(`📥 Downloading Alurkerja CLI ${version}...`);
90
62
 
91
63
  // Ensure install directory exists
92
64
  fs.mkdirSync(INSTALL_DIR, { recursive: true });
93
65
 
66
+ // Use temporary file to avoid ETXTBSY error
67
+ const tempPath = `${BINARY_PATH}.tmp`;
68
+
94
69
  return new Promise((resolve, reject) => {
95
- const file = fs.createWriteStream(BINARY_PATH);
70
+ const file = fs.createWriteStream(tempPath);
71
+
72
+ const url = new URL(downloadUrl);
73
+ const options = {
74
+ hostname: url.hostname,
75
+ path: url.pathname + url.search,
76
+ headers: {
77
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
78
+ }
79
+ };
96
80
 
97
- const req = https.get(downloadUrl, (res) => {
81
+ const req = https.get(options, (res) => {
98
82
  if (res.statusCode === 302 || res.statusCode === 301) {
99
- // Follow redirect
100
- return https.get(res.headers.location, (redirectRes) => {
83
+ // Follow redirect with token
84
+ const redirectUrl = new URL(res.headers.location);
85
+ const redirectOptions = {
86
+ hostname: redirectUrl.hostname,
87
+ path: redirectUrl.pathname + redirectUrl.search,
88
+ headers: {
89
+ 'PRIVATE-TOKEN': GITLAB_TOKEN
90
+ }
91
+ };
92
+ return https.get(redirectOptions, (redirectRes) => {
101
93
  redirectRes.pipe(file);
102
- redirectRes.on('end', resolve);
103
94
  });
104
95
  }
105
96
 
106
97
  if (res.statusCode !== 200) {
98
+ file.close();
99
+ fs.unlinkSync(tempPath);
107
100
  reject(new Error(`Download failed with status ${res.statusCode}`));
108
101
  return;
109
102
  }
110
103
 
111
104
  res.pipe(file);
112
- res.on('end', resolve);
113
105
  });
114
106
 
115
- req.on('error', reject);
107
+ req.on('error', (err) => {
108
+ file.close();
109
+ try { fs.unlinkSync(tempPath); } catch {}
110
+ reject(err);
111
+ });
112
+
116
113
  req.setTimeout(30000, () => {
117
114
  req.abort();
115
+ file.close();
116
+ try { fs.unlinkSync(tempPath); } catch {}
118
117
  reject(new Error('Download timeout'));
119
118
  });
120
119
 
121
- file.on('error', reject);
120
+ file.on('error', (err) => {
121
+ try { fs.unlinkSync(tempPath); } catch {}
122
+ reject(err);
123
+ });
124
+
122
125
  file.on('finish', () => {
123
- file.close();
124
- // Make executable on Unix systems
125
- if (platform.os !== 'windows') {
126
- fs.chmodSync(BINARY_PATH, '755');
127
- }
126
+ file.close((err) => {
127
+ if (err) {
128
+ try { fs.unlinkSync(tempPath); } catch {}
129
+ reject(err);
130
+ return;
131
+ }
132
+
133
+ // Make executable on Unix systems before renaming
134
+ if (platform.os !== 'windows') {
135
+ try {
136
+ fs.chmodSync(tempPath, '755');
137
+ } catch (err) {
138
+ try { fs.unlinkSync(tempPath); } catch {}
139
+ reject(new Error(`Failed to make binary executable: ${err.message}`));
140
+ return;
141
+ }
142
+ }
143
+
144
+ // Rename temp file to final path
145
+ try {
146
+ // Remove old binary if exists
147
+ if (fs.existsSync(BINARY_PATH)) {
148
+ fs.unlinkSync(BINARY_PATH);
149
+ }
150
+ fs.renameSync(tempPath, BINARY_PATH);
151
+ resolve();
152
+ } catch (err) {
153
+ try { fs.unlinkSync(tempPath); } catch {}
154
+ reject(new Error(`Failed to install binary: ${err.message}`));
155
+ }
156
+ });
128
157
  });
129
158
  });
130
159
  }
@@ -179,16 +208,16 @@ function executeBinary(args) {
179
208
  async function bootstrap() {
180
209
  try {
181
210
  const platform = detectPlatform();
182
- const latestVersion = await getLatestVersion();
211
+ const version = getVersion();
183
212
  const installedVersion = getInstalledVersion();
184
213
 
185
214
  // Check if we need to download the binary
186
215
  const needsDownload = !binaryExists() ||
187
- (installedVersion !== latestVersion && latestVersion !== 'dev');
216
+ (installedVersion !== version && version !== 'dev');
188
217
 
189
218
  if (needsDownload) {
190
- await downloadBinary(latestVersion, platform);
191
- console.log(`✅ Alurkerja CLI ${latestVersion} ready!`);
219
+ await downloadBinary(version, platform);
220
+ console.log(`✅ Alurkerja CLI ${version} ready!`);
192
221
  }
193
222
 
194
223
  // Execute the binary with all arguments passed to this script
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alurkerja-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Alurkerja CLI - npx wrapper for Go binary",
5
5
  "main": "index.js",
6
6
  "private": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alurkerja-cli",
3
- "version": "0.0.1",
3
+ "version": "1.0.0",
4
4
  "description": "Alurkerja CLI - npx wrapper for Go binary",
5
5
  "main": "index.js",
6
6
  "private": false,