@xano/cli 0.0.10 → 0.0.12

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.
@@ -0,0 +1,146 @@
1
+ import { Flags } from '@oclif/core';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ import * as yaml from 'js-yaml';
6
+ import BaseCommand from '../../../base-command.js';
7
+ export default class ProfileMe extends BaseCommand {
8
+ static flags = {
9
+ ...BaseCommand.baseFlags,
10
+ output: Flags.string({
11
+ char: 'o',
12
+ description: 'Output format',
13
+ required: false,
14
+ default: 'summary',
15
+ options: ['summary', 'json'],
16
+ }),
17
+ };
18
+ static description = 'Get information about the currently authenticated user';
19
+ static examples = [
20
+ `$ xano profile:me
21
+ User Information:
22
+ ID: 1
23
+ Name: John Doe
24
+ Email: john@example.com
25
+ `,
26
+ `$ xano profile:me --profile production
27
+ User Information:
28
+ ID: 42
29
+ Name: Admin User
30
+ Email: admin@example.com
31
+ `,
32
+ `$ xano profile:me --output json
33
+ {
34
+ "id": 1,
35
+ "name": "John Doe",
36
+ "email": "john@example.com"
37
+ }
38
+ `,
39
+ ];
40
+ async run() {
41
+ const { flags } = await this.parse(ProfileMe);
42
+ // Get profile name (default or from flag/env)
43
+ const profileName = flags.profile || this.getDefaultProfile();
44
+ // Load credentials
45
+ const credentials = this.loadCredentials();
46
+ // Get the profile configuration
47
+ if (!(profileName in credentials.profiles)) {
48
+ this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
49
+ `Create a profile using 'xano profile:create'`);
50
+ }
51
+ const profile = credentials.profiles[profileName];
52
+ // Validate required fields
53
+ if (!profile.instance_origin) {
54
+ this.error(`Profile '${profileName}' is missing instance_origin`);
55
+ }
56
+ if (!profile.access_token) {
57
+ this.error(`Profile '${profileName}' is missing access_token`);
58
+ }
59
+ // Construct the API URL
60
+ const apiUrl = `${profile.instance_origin}/api:meta/auth/me`;
61
+ // Fetch user info from the API
62
+ try {
63
+ const response = await fetch(apiUrl, {
64
+ method: 'GET',
65
+ headers: {
66
+ 'accept': 'application/json',
67
+ 'Authorization': `Bearer ${profile.access_token}`,
68
+ },
69
+ });
70
+ if (!response.ok) {
71
+ const errorText = await response.text();
72
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
73
+ }
74
+ const data = await response.json();
75
+ // Output results
76
+ if (flags.output === 'json') {
77
+ this.log(JSON.stringify(data, null, 2));
78
+ }
79
+ else {
80
+ // summary format
81
+ this.log('User Information:');
82
+ if (data.id !== undefined) {
83
+ this.log(` ID: ${data.id}`);
84
+ }
85
+ if (data.name) {
86
+ this.log(` Name: ${data.name}`);
87
+ }
88
+ if (data.email) {
89
+ this.log(` Email: ${data.email}`);
90
+ }
91
+ if (data.created_at) {
92
+ const date = new Date(data.created_at * 1000);
93
+ this.log(` Created: ${date.toISOString()}`);
94
+ }
95
+ // Display any other fields that aren't already shown
96
+ const knownFields = ['id', 'name', 'email', 'created_at'];
97
+ for (const [key, value] of Object.entries(data)) {
98
+ if (!knownFields.includes(key) && value !== null && value !== undefined) {
99
+ if (typeof value === 'object') {
100
+ this.log(` ${this.formatKey(key)}: ${JSON.stringify(value)}`);
101
+ }
102
+ else {
103
+ this.log(` ${this.formatKey(key)}: ${value}`);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ catch (error) {
110
+ if (error instanceof Error) {
111
+ this.error(`Failed to fetch user info: ${error.message}`);
112
+ }
113
+ else {
114
+ this.error(`Failed to fetch user info: ${String(error)}`);
115
+ }
116
+ }
117
+ }
118
+ loadCredentials() {
119
+ const configDir = path.join(os.homedir(), '.xano');
120
+ const credentialsPath = path.join(configDir, 'credentials.yaml');
121
+ // Check if credentials file exists
122
+ if (!fs.existsSync(credentialsPath)) {
123
+ this.error(`Credentials file not found at ${credentialsPath}\n` +
124
+ `Create a profile using 'xano profile:create'`);
125
+ }
126
+ // Read credentials file
127
+ try {
128
+ const fileContent = fs.readFileSync(credentialsPath, 'utf8');
129
+ const parsed = yaml.load(fileContent);
130
+ if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
131
+ this.error('Credentials file has invalid format.');
132
+ }
133
+ return parsed;
134
+ }
135
+ catch (error) {
136
+ this.error(`Failed to parse credentials file: ${error}`);
137
+ }
138
+ }
139
+ formatKey(key) {
140
+ // Convert snake_case to Title Case
141
+ return key
142
+ .split('_')
143
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
144
+ .join(' ');
145
+ }
146
+ }