@hiyve/cli 1.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/README.md +104 -0
- package/bin/hiyve.js +47 -0
- package/package.json +45 -0
- package/src/commands/list.js +82 -0
- package/src/commands/login.js +150 -0
- package/src/commands/logout.js +44 -0
- package/src/commands/whoami.js +70 -0
- package/src/config.js +10 -0
- package/src/index.js +11 -0
- package/src/utils/npmrc.js +117 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# hiyve-cli
|
|
2
|
+
|
|
3
|
+
Command-line tool for configuring npm to use the private Hiyve SDK registry.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# One command to authenticate and configure npm
|
|
9
|
+
npx hiyve-cli login
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
After login, you can install Hiyve packages normally:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @hiyve/rtc-client
|
|
16
|
+
npm install @hiyve/auth
|
|
17
|
+
npm install @hiyve/auth-react
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
### `hiyve login`
|
|
23
|
+
|
|
24
|
+
Authenticate with Hiyve and configure npm for @hiyve packages.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Interactive mode (prompts for API key)
|
|
28
|
+
npx hiyve-cli login
|
|
29
|
+
|
|
30
|
+
# With API key as argument
|
|
31
|
+
npx hiyve-cli login --key mk_your_api_key_here
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### `hiyve logout`
|
|
35
|
+
|
|
36
|
+
Remove Hiyve configuration from your ~/.npmrc file.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx hiyve-cli logout
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `hiyve whoami`
|
|
43
|
+
|
|
44
|
+
Show current authentication status.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx hiyve-cli whoami
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Getting Your API Key
|
|
51
|
+
|
|
52
|
+
1. Log in to the [Hiyve SDK Admin Portal](https://console.hiyve.dev)
|
|
53
|
+
2. Navigate to **API Keys** in the sidebar
|
|
54
|
+
3. Copy your API key (starts with `mk_`)
|
|
55
|
+
|
|
56
|
+
## What Does Login Do?
|
|
57
|
+
|
|
58
|
+
The `login` command:
|
|
59
|
+
|
|
60
|
+
1. Validates your API key with the Hiyve registry
|
|
61
|
+
2. Adds two lines to your `~/.npmrc` file:
|
|
62
|
+
- `@hiyve:registry=https://console.hiyve.dev/api/registry/`
|
|
63
|
+
- `//:_authToken=your_api_key`
|
|
64
|
+
|
|
65
|
+
This tells npm to fetch `@hiyve/*` packages from the private Hiyve registry instead of the public npm registry.
|
|
66
|
+
|
|
67
|
+
## Troubleshooting
|
|
68
|
+
|
|
69
|
+
### "Invalid API key" error
|
|
70
|
+
|
|
71
|
+
- Make sure your API key starts with `mk_`
|
|
72
|
+
- Check that your API key is 35 characters long
|
|
73
|
+
- Verify your account is active in the admin portal
|
|
74
|
+
|
|
75
|
+
### "Connection failed" error
|
|
76
|
+
|
|
77
|
+
- Check your internet connection
|
|
78
|
+
- The registry may be temporarily unavailable
|
|
79
|
+
|
|
80
|
+
### Packages not installing
|
|
81
|
+
|
|
82
|
+
After login, verify your configuration:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx hiyve-cli whoami
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Or check your `~/.npmrc` manually:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cat ~/.npmrc | grep hiyve
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Security
|
|
95
|
+
|
|
96
|
+
- Your API key is stored in `~/.npmrc` (standard npm token storage)
|
|
97
|
+
- The API key is sent only to `console.hiyve.dev`
|
|
98
|
+
- Run `hiyve logout` to remove your credentials
|
|
99
|
+
|
|
100
|
+
## Support
|
|
101
|
+
|
|
102
|
+
- Documentation: https://docs.hiyve.io
|
|
103
|
+
- Issues: https://github.com/hiyve/hiyve-sdk/issues
|
|
104
|
+
- Email: support@hiyve.io
|
package/bin/hiyve.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hiyve CLI - Main entry point
|
|
5
|
+
*
|
|
6
|
+
* Configures npm to use the private Hiyve registry for @hiyve packages.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { program } from 'commander';
|
|
10
|
+
import { login } from '../src/commands/login.js';
|
|
11
|
+
import { logout } from '../src/commands/logout.js';
|
|
12
|
+
import { whoami } from '../src/commands/whoami.js';
|
|
13
|
+
import { list } from '../src/commands/list.js';
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name('hiyve')
|
|
17
|
+
.description('Hiyve SDK CLI - Configure npm for private @hiyve packages')
|
|
18
|
+
.version('1.0.0');
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.command('login')
|
|
22
|
+
.description('Authenticate with Hiyve and configure npm for @hiyve packages')
|
|
23
|
+
.option('-k, --key <apiKey>', 'API key (or will prompt interactively)')
|
|
24
|
+
.action(login);
|
|
25
|
+
|
|
26
|
+
program
|
|
27
|
+
.command('logout')
|
|
28
|
+
.description('Remove Hiyve npm configuration from ~/.npmrc')
|
|
29
|
+
.action(logout);
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('whoami')
|
|
33
|
+
.description('Show current authentication status')
|
|
34
|
+
.action(whoami);
|
|
35
|
+
|
|
36
|
+
program
|
|
37
|
+
.command('list')
|
|
38
|
+
.alias('ls')
|
|
39
|
+
.description('List all available @hiyve packages')
|
|
40
|
+
.action(list);
|
|
41
|
+
|
|
42
|
+
// Show help if no command provided
|
|
43
|
+
program.parse();
|
|
44
|
+
|
|
45
|
+
if (process.argv.length <= 2) {
|
|
46
|
+
program.help();
|
|
47
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hiyve/cli",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "Hiyve SDK CLI - Configure npm for private @hiyve packages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"hiyve": "./bin/hiyve.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "src/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "echo \"No tests yet\"",
|
|
16
|
+
"deploy": "./deploy.sh"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"hiyve",
|
|
20
|
+
"sdk",
|
|
21
|
+
"cli",
|
|
22
|
+
"webrtc",
|
|
23
|
+
"npm",
|
|
24
|
+
"registry"
|
|
25
|
+
],
|
|
26
|
+
"author": "Hiyve, IWantToPractice, LLC",
|
|
27
|
+
"license": "Commercial",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/hiyve/hiyve-sdk"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"registry": "https://registry.npmjs.org/",
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"chalk": "^5.3.0",
|
|
41
|
+
"commander": "^12.1.0",
|
|
42
|
+
"ora": "^8.1.0",
|
|
43
|
+
"prompts": "^2.4.2"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List Command
|
|
3
|
+
*
|
|
4
|
+
* Shows all available @hiyve packages from the registry.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { REGISTRY_URL } from '../config.js';
|
|
10
|
+
import { getCurrentConfig } from '../utils/npmrc.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* List available packages
|
|
14
|
+
*/
|
|
15
|
+
export async function list() {
|
|
16
|
+
console.log('');
|
|
17
|
+
console.log(chalk.cyan('Available @hiyve Packages'));
|
|
18
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
19
|
+
console.log('');
|
|
20
|
+
|
|
21
|
+
// Get current config for auth token
|
|
22
|
+
const config = getCurrentConfig();
|
|
23
|
+
|
|
24
|
+
if (!config?.apiKey) {
|
|
25
|
+
console.log(chalk.yellow('Not authenticated. Run `hiyve login` first.'));
|
|
26
|
+
console.log('');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const spinner = ora('Fetching packages...').start();
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(`${REGISTRY_URL}packages`, {
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
spinner.fail('Failed to fetch packages');
|
|
41
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(chalk.red(` ${error.error || 'Failed to fetch packages'}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const data = await response.json();
|
|
48
|
+
spinner.succeed(`Found ${data.total} packages`);
|
|
49
|
+
console.log('');
|
|
50
|
+
|
|
51
|
+
// Display SDK packages
|
|
52
|
+
if (data.sdk?.length > 0) {
|
|
53
|
+
console.log(chalk.white.bold('SDK Packages:'));
|
|
54
|
+
for (const pkg of data.sdk) {
|
|
55
|
+
console.log(chalk.cyan(` ${pkg.name}`));
|
|
56
|
+
}
|
|
57
|
+
console.log('');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Display component packages
|
|
61
|
+
if (data.components?.length > 0) {
|
|
62
|
+
console.log(chalk.white.bold('Component Packages:'));
|
|
63
|
+
for (const pkg of data.components) {
|
|
64
|
+
console.log(chalk.cyan(` ${pkg.name}`));
|
|
65
|
+
}
|
|
66
|
+
console.log('');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Usage hint
|
|
70
|
+
console.log(chalk.gray('Install with:'));
|
|
71
|
+
console.log(chalk.gray(' npm install <package-name>'));
|
|
72
|
+
console.log('');
|
|
73
|
+
} catch (err) {
|
|
74
|
+
spinner.fail('Connection failed');
|
|
75
|
+
console.log('');
|
|
76
|
+
console.log(chalk.red(` ${err.message}`));
|
|
77
|
+
console.log(chalk.gray(' Please check your internet connection'));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default list;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Login Command
|
|
3
|
+
*
|
|
4
|
+
* Authenticates with Hiyve registry and configures npm for @hiyve packages.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import prompts from 'prompts';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import { configureNpmrc } from '../utils/npmrc.js';
|
|
11
|
+
import { REGISTRY_URL } from '../config.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Login to Hiyve and configure npm
|
|
15
|
+
* @param {Object} options - Command options
|
|
16
|
+
* @param {string} [options.key] - API key (optional, will prompt if not provided)
|
|
17
|
+
*/
|
|
18
|
+
export async function login(options) {
|
|
19
|
+
let apiKey = options.key;
|
|
20
|
+
|
|
21
|
+
console.log('');
|
|
22
|
+
console.log(chalk.cyan('Hiyve SDK Authentication'));
|
|
23
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
24
|
+
console.log('');
|
|
25
|
+
|
|
26
|
+
// Prompt for API key if not provided
|
|
27
|
+
if (!apiKey) {
|
|
28
|
+
const response = await prompts({
|
|
29
|
+
type: 'password',
|
|
30
|
+
name: 'apiKey',
|
|
31
|
+
message: 'Enter your Hiyve API key:',
|
|
32
|
+
validate: (value) => {
|
|
33
|
+
if (!value) return 'API key is required';
|
|
34
|
+
if (!value.startsWith('mk_')) return 'API key should start with mk_';
|
|
35
|
+
if (value.length < 35) return 'API key appears to be too short';
|
|
36
|
+
return true;
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!response.apiKey) {
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(chalk.yellow('Login cancelled.'));
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
apiKey = response.apiKey;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Validate API key format
|
|
50
|
+
if (!apiKey.match(/^mk_[a-fA-F0-9]{32}$/)) {
|
|
51
|
+
console.log('');
|
|
52
|
+
console.log(chalk.red('✗ Invalid API key format'));
|
|
53
|
+
console.log(chalk.gray(' API key should be 35 characters: mk_ followed by 32 hex characters'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Verify API key with registry
|
|
58
|
+
const spinner = ora('Verifying API key...').start();
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(`${REGISTRY_URL}verify`, {
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: `Bearer ${apiKey}`,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
69
|
+
spinner.fail('API key verification failed');
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log(chalk.red(` ${error.error || 'Invalid API key'}`));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const data = await response.json();
|
|
76
|
+
spinner.succeed('API key verified');
|
|
77
|
+
|
|
78
|
+
if (data.apiKey) {
|
|
79
|
+
console.log(chalk.gray(` Account: ${data.apiKey}`));
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
spinner.fail('Connection failed');
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log(chalk.red(` ${err.message}`));
|
|
85
|
+
console.log(chalk.gray(' Please check your internet connection'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Configure .npmrc
|
|
90
|
+
const spinner2 = ora('Configuring npm...').start();
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
await configureNpmrc(REGISTRY_URL, apiKey);
|
|
94
|
+
spinner2.succeed('npm configured for @hiyve packages');
|
|
95
|
+
} catch (err) {
|
|
96
|
+
spinner2.fail('Failed to configure npm');
|
|
97
|
+
console.log('');
|
|
98
|
+
console.log(chalk.red(` ${err.message}`));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Success message
|
|
103
|
+
console.log('');
|
|
104
|
+
console.log(chalk.green('✓ Setup complete!'));
|
|
105
|
+
console.log('');
|
|
106
|
+
|
|
107
|
+
// Fetch available packages from registry
|
|
108
|
+
try {
|
|
109
|
+
const packagesResponse = await fetch(`${REGISTRY_URL}packages`, {
|
|
110
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (packagesResponse.ok) {
|
|
114
|
+
const packages = await packagesResponse.json();
|
|
115
|
+
|
|
116
|
+
console.log(`You can now install ${packages.total} Hiyve packages:`);
|
|
117
|
+
console.log('');
|
|
118
|
+
|
|
119
|
+
if (packages.sdk?.length > 0) {
|
|
120
|
+
console.log(chalk.gray(' SDK packages:'));
|
|
121
|
+
for (const pkg of packages.sdk) {
|
|
122
|
+
console.log(chalk.cyan(` npm install ${pkg.name}`));
|
|
123
|
+
}
|
|
124
|
+
console.log('');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (packages.components?.length > 0) {
|
|
128
|
+
console.log(chalk.gray(' Component packages:'));
|
|
129
|
+
for (const pkg of packages.components) {
|
|
130
|
+
console.log(chalk.cyan(` npm install ${pkg.name}`));
|
|
131
|
+
}
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
// Fallback if packages endpoint fails
|
|
136
|
+
console.log('You can now install Hiyve packages:');
|
|
137
|
+
console.log(chalk.cyan(' npm install @hiyve/rtc-client'));
|
|
138
|
+
console.log(chalk.cyan(' npm install @hiyve/client-provider'));
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
141
|
+
} catch {
|
|
142
|
+
// Fallback on network error
|
|
143
|
+
console.log('You can now install Hiyve packages:');
|
|
144
|
+
console.log(chalk.cyan(' npm install @hiyve/rtc-client'));
|
|
145
|
+
console.log(chalk.cyan(' npm install @hiyve/client-provider'));
|
|
146
|
+
console.log('');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export default login;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logout Command
|
|
3
|
+
*
|
|
4
|
+
* Removes Hiyve configuration from ~/.npmrc
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { removeNpmrc, getCurrentConfig } from '../utils/npmrc.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Remove Hiyve npm configuration
|
|
13
|
+
*/
|
|
14
|
+
export async function logout() {
|
|
15
|
+
console.log('');
|
|
16
|
+
|
|
17
|
+
// Check if currently configured
|
|
18
|
+
const currentConfig = getCurrentConfig();
|
|
19
|
+
|
|
20
|
+
if (!currentConfig) {
|
|
21
|
+
console.log(chalk.yellow('You are not logged in to Hiyve.'));
|
|
22
|
+
console.log('');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const spinner = ora('Removing Hiyve configuration...').start();
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await removeNpmrc();
|
|
30
|
+
spinner.succeed('Hiyve npm configuration removed');
|
|
31
|
+
} catch (err) {
|
|
32
|
+
spinner.fail('Failed to remove configuration');
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(chalk.red(` ${err.message}`));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(chalk.green('✓ Logged out successfully'));
|
|
40
|
+
console.log(chalk.gray(' @hiyve packages will no longer be accessible via npm'));
|
|
41
|
+
console.log('');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default logout;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whoami Command
|
|
3
|
+
*
|
|
4
|
+
* Shows current Hiyve authentication status
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { getCurrentConfig } from '../utils/npmrc.js';
|
|
10
|
+
import { REGISTRY_URL } from '../config.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Show current authentication status
|
|
14
|
+
*/
|
|
15
|
+
export async function whoami() {
|
|
16
|
+
console.log('');
|
|
17
|
+
console.log(chalk.cyan('Hiyve Authentication Status'));
|
|
18
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
19
|
+
console.log('');
|
|
20
|
+
|
|
21
|
+
// Check local config
|
|
22
|
+
const config = getCurrentConfig();
|
|
23
|
+
|
|
24
|
+
if (!config) {
|
|
25
|
+
console.log(chalk.yellow('Not logged in'));
|
|
26
|
+
console.log('');
|
|
27
|
+
console.log('Run ' + chalk.cyan('hiyve login') + ' to authenticate');
|
|
28
|
+
console.log('');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(chalk.gray('Local configuration:'));
|
|
33
|
+
console.log(` Registry: ${chalk.green('configured')}`);
|
|
34
|
+
console.log(` API Key: ${chalk.cyan(config.maskedApiKey)}`);
|
|
35
|
+
console.log('');
|
|
36
|
+
|
|
37
|
+
// Verify with server
|
|
38
|
+
if (config.apiKey) {
|
|
39
|
+
const spinner = ora('Verifying with server...').start();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(`${REGISTRY_URL}verify`, {
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (response.ok) {
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
spinner.succeed('API key is valid');
|
|
51
|
+
|
|
52
|
+
if (data.email) {
|
|
53
|
+
console.log(` Email: ${chalk.cyan(data.email)}`);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
spinner.warn('API key may be invalid or expired');
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log(chalk.yellow(' Your API key is configured locally but failed server validation.'));
|
|
59
|
+
console.log(chalk.yellow(' Run ' + chalk.cyan('hiyve login') + ' to re-authenticate.'));
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
spinner.warn('Could not verify with server');
|
|
63
|
+
console.log(chalk.gray(` ${err.message}`));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default whoami;
|
package/src/config.js
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hiyve CLI - Public API
|
|
3
|
+
*
|
|
4
|
+
* This module exports the CLI commands for programmatic use.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { login } from './commands/login.js';
|
|
8
|
+
export { logout } from './commands/logout.js';
|
|
9
|
+
export { whoami } from './commands/whoami.js';
|
|
10
|
+
export { configureNpmrc, removeNpmrc, getCurrentConfig } from './utils/npmrc.js';
|
|
11
|
+
export { REGISTRY_URL, SCOPED_PACKAGES } from './config.js';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npmrc Utilities
|
|
3
|
+
*
|
|
4
|
+
* Functions for reading and modifying the user's ~/.npmrc file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import os from 'os';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
|
|
11
|
+
const NPMRC_PATH = path.join(os.homedir(), '.npmrc');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Configure ~/.npmrc for Hiyve registry
|
|
15
|
+
* @param {string} registryUrl - The registry URL (e.g., https://console.hiyve.dev/api/registry/)
|
|
16
|
+
* @param {string} apiKey - The API key for authentication
|
|
17
|
+
*/
|
|
18
|
+
export async function configureNpmrc(registryUrl, apiKey) {
|
|
19
|
+
let content = '';
|
|
20
|
+
|
|
21
|
+
// Read existing .npmrc if it exists
|
|
22
|
+
if (fs.existsSync(NPMRC_PATH)) {
|
|
23
|
+
content = fs.readFileSync(NPMRC_PATH, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Remove any existing @hiyve config lines
|
|
27
|
+
const lines = content.split('\n').filter((line) => {
|
|
28
|
+
const trimmed = line.trim();
|
|
29
|
+
return (
|
|
30
|
+
!trimmed.startsWith('@hiyve:registry') &&
|
|
31
|
+
!trimmed.includes('//console.hiyve.dev/') &&
|
|
32
|
+
!trimmed.includes(':_authToken=mk_')
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Parse the registry URL to extract host
|
|
37
|
+
const url = new URL(registryUrl);
|
|
38
|
+
const registryHost = url.host;
|
|
39
|
+
|
|
40
|
+
// Add new config lines
|
|
41
|
+
lines.push(`@hiyve:registry=${registryUrl}`);
|
|
42
|
+
lines.push(`//${registryHost}/api/registry/:_authToken=${apiKey}`);
|
|
43
|
+
|
|
44
|
+
// Write back, removing empty lines at start/end
|
|
45
|
+
const finalContent = lines.filter((line) => line.trim()).join('\n') + '\n';
|
|
46
|
+
fs.writeFileSync(NPMRC_PATH, finalContent, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Remove Hiyve configuration from ~/.npmrc
|
|
51
|
+
*/
|
|
52
|
+
export async function removeNpmrc() {
|
|
53
|
+
if (!fs.existsSync(NPMRC_PATH)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const content = fs.readFileSync(NPMRC_PATH, 'utf8');
|
|
58
|
+
|
|
59
|
+
// Remove @hiyve config lines
|
|
60
|
+
const lines = content.split('\n').filter((line) => {
|
|
61
|
+
const trimmed = line.trim();
|
|
62
|
+
return (
|
|
63
|
+
!trimmed.startsWith('@hiyve:registry') &&
|
|
64
|
+
!trimmed.includes('//console.hiyve.dev/') &&
|
|
65
|
+
!trimmed.includes(':_authToken=mk_')
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Write back
|
|
70
|
+
const finalContent = lines.filter((line) => line.trim()).join('\n');
|
|
71
|
+
fs.writeFileSync(NPMRC_PATH, finalContent ? finalContent + '\n' : '', 'utf8');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get current Hiyve configuration from ~/.npmrc
|
|
76
|
+
* @returns {Object|null} Current config or null if not configured
|
|
77
|
+
*/
|
|
78
|
+
export function getCurrentConfig() {
|
|
79
|
+
if (!fs.existsSync(NPMRC_PATH)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const content = fs.readFileSync(NPMRC_PATH, 'utf8');
|
|
84
|
+
const lines = content.split('\n');
|
|
85
|
+
|
|
86
|
+
// Find registry line
|
|
87
|
+
const registryLine = lines.find((line) => line.trim().startsWith('@hiyve:registry'));
|
|
88
|
+
|
|
89
|
+
// Find token line
|
|
90
|
+
const tokenLine = lines.find((line) => {
|
|
91
|
+
const trimmed = line.trim();
|
|
92
|
+
return trimmed.includes(':_authToken=mk_');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!registryLine || !tokenLine) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Extract API key
|
|
100
|
+
const tokenMatch = tokenLine.match(/:_authToken=(mk_[a-fA-F0-9]+)/);
|
|
101
|
+
const apiKey = tokenMatch ? tokenMatch[1] : null;
|
|
102
|
+
|
|
103
|
+
// Mask API key for display
|
|
104
|
+
const maskedApiKey = apiKey ? `${apiKey.slice(0, 6)}...${apiKey.slice(-4)}` : null;
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
apiKey,
|
|
108
|
+
maskedApiKey,
|
|
109
|
+
registryUrl: registryLine.split('=')[1]?.trim(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default {
|
|
114
|
+
configureNpmrc,
|
|
115
|
+
removeNpmrc,
|
|
116
|
+
getCurrentConfig,
|
|
117
|
+
};
|