@myvillage/cli 1.2.0 → 1.2.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/package.json +1 -1
- package/src/commands/login.js +1 -0
- package/src/commands/post.js +3 -3
- package/src/commands/profile.js +11 -3
- package/src/utils/api.js +6 -3
- package/src/utils/auth.js +7 -0
package/package.json
CHANGED
package/src/commands/login.js
CHANGED
package/src/commands/post.js
CHANGED
|
@@ -111,9 +111,9 @@ export async function postCreateCommand() {
|
|
|
111
111
|
message: 'Title (optional):',
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
|
-
type: '
|
|
114
|
+
type: 'input',
|
|
115
115
|
name: 'body',
|
|
116
|
-
message: 'Post body
|
|
116
|
+
message: 'Post body:',
|
|
117
117
|
validate: (input) => input.trim().length > 0 || 'Body is required',
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -203,7 +203,7 @@ export async function postEditCommand(id) {
|
|
|
203
203
|
|
|
204
204
|
const answers = await inquirer.prompt([
|
|
205
205
|
{
|
|
206
|
-
type: '
|
|
206
|
+
type: 'input',
|
|
207
207
|
name: 'body',
|
|
208
208
|
message: 'Edit post body:',
|
|
209
209
|
default: post.body,
|
package/src/commands/profile.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { isAuthenticated } from '../utils/auth.js';
|
|
3
|
+
import { isAuthenticated, loadCredentials } from '../utils/auth.js';
|
|
4
4
|
import { getProfile, getProfilePosts } from '../utils/api.js';
|
|
5
5
|
import { formatProfile, formatPostList, formatPagination } from '../utils/formatters.js';
|
|
6
6
|
|
|
@@ -10,8 +10,16 @@ export async function profileCommand(handle, options) {
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
//
|
|
14
|
-
|
|
13
|
+
// Resolve handle: default to the logged-in user's villagerId
|
|
14
|
+
let target = handle;
|
|
15
|
+
if (!target) {
|
|
16
|
+
const creds = loadCredentials();
|
|
17
|
+
target = creds?.villager_id;
|
|
18
|
+
if (!target) {
|
|
19
|
+
console.log(chalk.red(' ✗ No villager ID found. Try logging out and back in, or provide a handle: myvillage profile <handle>'));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
15
23
|
const spinner = ora('Loading profile...').start();
|
|
16
24
|
|
|
17
25
|
try {
|
package/src/utils/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { getConfig } from './config.js';
|
|
3
|
-
import { loadCredentials, saveCredentials, getAccessToken } from './auth.js';
|
|
3
|
+
import { loadCredentials, saveCredentials, getAccessToken, isTokenExpired } from './auth.js';
|
|
4
4
|
|
|
5
5
|
const USER_AGENT = 'MyVillageOS-CLI/1.0.0';
|
|
6
6
|
|
|
@@ -12,8 +12,11 @@ function createClient(baseURL) {
|
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
// Add auth token to requests
|
|
16
|
-
client.interceptors.request.use((reqConfig) => {
|
|
15
|
+
// Add auth token to requests, proactively refreshing if expired
|
|
16
|
+
client.interceptors.request.use(async (reqConfig) => {
|
|
17
|
+
if (isTokenExpired()) {
|
|
18
|
+
await refreshAccessToken();
|
|
19
|
+
}
|
|
17
20
|
const token = getAccessToken();
|
|
18
21
|
if (token) {
|
|
19
22
|
reqConfig.headers.Authorization = `Bearer ${token}`;
|
package/src/utils/auth.js
CHANGED
|
@@ -98,6 +98,13 @@ export function getAccessToken() {
|
|
|
98
98
|
return creds?.access_token || null;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
export function isTokenExpired() {
|
|
102
|
+
const creds = loadCredentials();
|
|
103
|
+
if (!creds?.expires_at) return false;
|
|
104
|
+
// Consider expired if within 60 seconds of expiry
|
|
105
|
+
return Date.now() >= (creds.expires_at - 60000);
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
export function getRefreshToken() {
|
|
102
109
|
const creds = loadCredentials();
|
|
103
110
|
return creds?.refresh_token || null;
|