carto-cli 0.1.0-rc.1
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/.nvmrc +1 -0
- package/ARCHITECTURE.md +497 -0
- package/CHANGELOG.md +28 -0
- package/LICENSE +15 -0
- package/MAP_JSON.md +516 -0
- package/README.md +1595 -0
- package/WORKFLOW_JSON.md +623 -0
- package/dist/api.js +489 -0
- package/dist/auth-oauth.js +485 -0
- package/dist/auth-server.js +432 -0
- package/dist/browser.js +30 -0
- package/dist/colors.js +45 -0
- package/dist/commands/activity.js +427 -0
- package/dist/commands/admin.js +177 -0
- package/dist/commands/ai.js +489 -0
- package/dist/commands/auth.js +652 -0
- package/dist/commands/connections.js +412 -0
- package/dist/commands/credentials.js +606 -0
- package/dist/commands/imports.js +234 -0
- package/dist/commands/maps.js +1022 -0
- package/dist/commands/org.js +195 -0
- package/dist/commands/sql.js +326 -0
- package/dist/commands/users.js +459 -0
- package/dist/commands/workflows.js +1025 -0
- package/dist/config.js +320 -0
- package/dist/download.js +108 -0
- package/dist/help.js +285 -0
- package/dist/http.js +139 -0
- package/dist/index.js +1133 -0
- package/dist/logo.js +11 -0
- package/dist/prompt.js +67 -0
- package/dist/schedule-parser.js +287 -0
- package/jest.config.ts +43 -0
- package/package.json +53 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usersList = usersList;
|
|
4
|
+
exports.usersGet = usersGet;
|
|
5
|
+
exports.usersInvite = usersInvite;
|
|
6
|
+
exports.usersResendInvitation = usersResendInvitation;
|
|
7
|
+
exports.usersCancelInvitation = usersCancelInvitation;
|
|
8
|
+
exports.usersDelete = usersDelete;
|
|
9
|
+
exports.usersInvitations = usersInvitations;
|
|
10
|
+
const api_1 = require("../api");
|
|
11
|
+
const colors_1 = require("../colors");
|
|
12
|
+
/**
|
|
13
|
+
* List all users in the organization
|
|
14
|
+
*/
|
|
15
|
+
async function usersList(options, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
16
|
+
try {
|
|
17
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
18
|
+
let users;
|
|
19
|
+
if (options.all) {
|
|
20
|
+
// Fetch all pages automatically
|
|
21
|
+
// Note: We'll use a simple pagination approach since we don't know the exact API pagination format
|
|
22
|
+
let page = 1;
|
|
23
|
+
const pageSize = 100;
|
|
24
|
+
const allUsers = [];
|
|
25
|
+
let hasMore = true;
|
|
26
|
+
while (hasMore) {
|
|
27
|
+
const params = new URLSearchParams();
|
|
28
|
+
params.append('page', page.toString());
|
|
29
|
+
params.append('page_size', pageSize.toString());
|
|
30
|
+
if (options.role)
|
|
31
|
+
params.append('role', options.role);
|
|
32
|
+
if (options.search)
|
|
33
|
+
params.append('search', options.search);
|
|
34
|
+
const queryString = params.toString();
|
|
35
|
+
const url = `/accounts/users${queryString ? '?' + queryString : ''}`;
|
|
36
|
+
const result = await client.getAccounts(url, true);
|
|
37
|
+
const pageUsers = Array.isArray(result) ? result : (result.data || result.results || []);
|
|
38
|
+
if (pageUsers.length === 0) {
|
|
39
|
+
hasMore = false;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
allUsers.push(...pageUsers);
|
|
43
|
+
if (pageUsers.length < pageSize) {
|
|
44
|
+
hasMore = false;
|
|
45
|
+
}
|
|
46
|
+
page++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
users = allUsers;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Fetch with pagination parameters or defaults
|
|
53
|
+
const params = new URLSearchParams();
|
|
54
|
+
if (options.page)
|
|
55
|
+
params.append('page', options.page);
|
|
56
|
+
if (options.pageSize)
|
|
57
|
+
params.append('page_size', options.pageSize);
|
|
58
|
+
if (options.role)
|
|
59
|
+
params.append('role', options.role);
|
|
60
|
+
if (options.search)
|
|
61
|
+
params.append('search', options.search);
|
|
62
|
+
const queryString = params.toString();
|
|
63
|
+
const url = `/accounts/users${queryString ? '?' + queryString : ''}`;
|
|
64
|
+
const result = await client.getAccounts(url, true);
|
|
65
|
+
users = Array.isArray(result) ? result : (result.data || result.results || []);
|
|
66
|
+
}
|
|
67
|
+
if (jsonOutput) {
|
|
68
|
+
console.log(JSON.stringify(users));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log((0, colors_1.bold)(`\nUsers (${users.length}):\n`));
|
|
72
|
+
users.forEach((user) => {
|
|
73
|
+
console.log((0, colors_1.bold)('Name: ') + (user.name || 'N/A'));
|
|
74
|
+
console.log(' Email: ' + user.email);
|
|
75
|
+
console.log(' User ID: ' + user.user_id);
|
|
76
|
+
if (user.app_metadata?.roles && user.app_metadata.roles.length > 0) {
|
|
77
|
+
console.log(' Roles: ' + user.app_metadata.roles.join(', '));
|
|
78
|
+
}
|
|
79
|
+
console.log(' Verified: ' + (user.email_verified ? 'Yes' : 'No'));
|
|
80
|
+
console.log(' Created: ' + new Date(user.created_at).toLocaleString());
|
|
81
|
+
if (user.user_metadata) {
|
|
82
|
+
console.log(' Organization: ' + user.user_metadata.account_name + ' (' + user.user_metadata.account_id + ')');
|
|
83
|
+
}
|
|
84
|
+
if (user.groups && user.groups.length > 0) {
|
|
85
|
+
console.log(' Groups: ' + user.groups.join(', '));
|
|
86
|
+
}
|
|
87
|
+
console.log('');
|
|
88
|
+
});
|
|
89
|
+
if (options.all) {
|
|
90
|
+
console.log((0, colors_1.dim)(`Fetched all ${users.length} users`));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (jsonOutput) {
|
|
96
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
100
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
101
|
+
console.log('Please run: carto auth login');
|
|
102
|
+
}
|
|
103
|
+
else if (err.message.includes('403')) {
|
|
104
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
105
|
+
console.log('You may not have sufficient permissions to view users.');
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.log((0, colors_1.error)('✗ Failed to list users: ' + err.message));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get detailed information about a specific user
|
|
116
|
+
*/
|
|
117
|
+
async function usersGet(userIdOrEmail, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
118
|
+
try {
|
|
119
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
120
|
+
// Search for the user (works for both email and user_id)
|
|
121
|
+
let searchTerm = userIdOrEmail;
|
|
122
|
+
// For user IDs, we need to search through all users since there's no GET /accounts/users/{id} endpoint
|
|
123
|
+
const searchUrl = `/accounts/users${searchTerm.includes('@') ? '?search=' + encodeURIComponent(searchTerm) : ''}`;
|
|
124
|
+
const searchResults = await client.getAccounts(searchUrl, true);
|
|
125
|
+
const users = Array.isArray(searchResults) ? searchResults : (searchResults.data || searchResults.results || []);
|
|
126
|
+
// Find exact match (by email or user_id)
|
|
127
|
+
let user;
|
|
128
|
+
if (userIdOrEmail.includes('@')) {
|
|
129
|
+
user = users.find((u) => u.email.toLowerCase() === userIdOrEmail.toLowerCase());
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
user = users.find((u) => u.user_id === userIdOrEmail);
|
|
133
|
+
}
|
|
134
|
+
if (!user) {
|
|
135
|
+
throw new Error(`User not found: ${userIdOrEmail}`);
|
|
136
|
+
}
|
|
137
|
+
if (jsonOutput) {
|
|
138
|
+
console.log(JSON.stringify(user));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.log((0, colors_1.bold)('\n=== User Details ===\n'));
|
|
142
|
+
console.log((0, colors_1.bold)('User ID: ') + user.user_id);
|
|
143
|
+
console.log((0, colors_1.bold)('Name: ') + (user.name || 'N/A'));
|
|
144
|
+
console.log((0, colors_1.bold)('Email: ') + user.email);
|
|
145
|
+
console.log((0, colors_1.bold)('Nickname: ') + (user.nickname || 'N/A'));
|
|
146
|
+
console.log((0, colors_1.bold)('Email Verified: ') + (user.email_verified ? 'Yes' : 'No'));
|
|
147
|
+
console.log((0, colors_1.bold)('Created: ') + new Date(user.created_at).toLocaleString());
|
|
148
|
+
if (user.picture) {
|
|
149
|
+
console.log((0, colors_1.bold)('Picture: ') + user.picture);
|
|
150
|
+
}
|
|
151
|
+
if (user.user_metadata) {
|
|
152
|
+
console.log((0, colors_1.bold)('\nOrganization:'));
|
|
153
|
+
console.log(' Account ID: ' + user.user_metadata.account_id);
|
|
154
|
+
console.log(' Account Name: ' + user.user_metadata.account_name);
|
|
155
|
+
console.log(' Tenant: ' + user.user_metadata.tenant_domain + ' (' + user.user_metadata.tenant_id + ')');
|
|
156
|
+
}
|
|
157
|
+
if (user.app_metadata?.roles && user.app_metadata.roles.length > 0) {
|
|
158
|
+
console.log((0, colors_1.bold)('\nRoles: ') + user.app_metadata.roles.join(', '));
|
|
159
|
+
}
|
|
160
|
+
if (user.groups && user.groups.length > 0) {
|
|
161
|
+
console.log((0, colors_1.bold)('\nGroups: ') + user.groups.join(', '));
|
|
162
|
+
}
|
|
163
|
+
if (user.identities && user.identities.length > 0) {
|
|
164
|
+
console.log((0, colors_1.bold)('\nIdentities:'));
|
|
165
|
+
user.identities.forEach((identity) => {
|
|
166
|
+
console.log(` - ${identity.provider} (${identity.connection})`);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
if (jsonOutput) {
|
|
173
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
177
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
178
|
+
console.log('Please run: carto auth login');
|
|
179
|
+
}
|
|
180
|
+
else if (err.message.includes('403')) {
|
|
181
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
182
|
+
console.log('You may not have sufficient permissions to view this user.');
|
|
183
|
+
}
|
|
184
|
+
else if (err.message.includes('404')) {
|
|
185
|
+
console.log((0, colors_1.error)('✗ User not found: ' + userIdOrEmail));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log((0, colors_1.error)('✗ Failed to get user details: ' + err.message));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Invite new users to the organization
|
|
196
|
+
*/
|
|
197
|
+
async function usersInvite(emails, role, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
198
|
+
try {
|
|
199
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
200
|
+
// Validate role
|
|
201
|
+
const validRoles = ['Builder', 'Viewer', 'Guest'];
|
|
202
|
+
if (!validRoles.includes(role)) {
|
|
203
|
+
throw new Error(`Invalid role: ${role}. Valid roles are: ${validRoles.join(', ')}`);
|
|
204
|
+
}
|
|
205
|
+
// Prepare request body
|
|
206
|
+
const body = {
|
|
207
|
+
email: emails,
|
|
208
|
+
target_role: role
|
|
209
|
+
};
|
|
210
|
+
const url = `/accounts/invite`;
|
|
211
|
+
const results = await client.postAccounts(url, body, true);
|
|
212
|
+
if (jsonOutput) {
|
|
213
|
+
console.log(JSON.stringify({ success: true, results }));
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.log((0, colors_1.success)('\n✓ Invitation(s) sent\n'));
|
|
217
|
+
results.forEach((result) => {
|
|
218
|
+
if (result.code === 200 && result.status === 'sent') {
|
|
219
|
+
console.log((0, colors_1.success)('✓ ') + result.destination + ' - ' + (0, colors_1.info)(result.status));
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
console.log((0, colors_1.error)('✗ ') + result.destination + ' - ' + (0, colors_1.error)(result.status));
|
|
223
|
+
if (result.message) {
|
|
224
|
+
console.log(' ' + (0, colors_1.dim)(result.message));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log((0, colors_1.info)(`Role: ${role}`));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
if (jsonOutput) {
|
|
234
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
238
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
239
|
+
console.log('Please run: carto auth login');
|
|
240
|
+
}
|
|
241
|
+
else if (err.message.includes('403')) {
|
|
242
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
243
|
+
console.log('You may not have sufficient permissions to invite users.');
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
console.log((0, colors_1.error)('✗ Failed to invite users: ' + err.message));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Resend a pending invitation
|
|
254
|
+
*/
|
|
255
|
+
async function usersResendInvitation(token, apiToken, baseUrl, jsonOutput, debug = false, profile) {
|
|
256
|
+
try {
|
|
257
|
+
const client = await api_1.ApiClient.create(apiToken, baseUrl, debug, profile);
|
|
258
|
+
const url = `/accounts/invitations/re-send`;
|
|
259
|
+
const body = { token };
|
|
260
|
+
const result = await client.postAccounts(url, body, true);
|
|
261
|
+
if (jsonOutput) {
|
|
262
|
+
console.log(JSON.stringify({ success: true, ...result }));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.log((0, colors_1.success)('\n✓ Invitation resent successfully\n'));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (jsonOutput) {
|
|
270
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
274
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
275
|
+
console.log('Please run: carto auth login');
|
|
276
|
+
}
|
|
277
|
+
else if (err.message.includes('403')) {
|
|
278
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
279
|
+
console.log('You may not have sufficient permissions to resend invitations.');
|
|
280
|
+
}
|
|
281
|
+
else if (err.message.includes('404')) {
|
|
282
|
+
console.log((0, colors_1.error)('✗ Invitation not found'));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
console.log((0, colors_1.error)('✗ Failed to resend invitation: ' + err.message));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Cancel a pending invitation
|
|
293
|
+
*/
|
|
294
|
+
async function usersCancelInvitation(token, apiToken, baseUrl, jsonOutput, debug = false, profile) {
|
|
295
|
+
try {
|
|
296
|
+
const client = await api_1.ApiClient.create(apiToken, baseUrl, debug, profile);
|
|
297
|
+
const url = `/accounts/invite/${token}`;
|
|
298
|
+
const response = await client.deleteAccounts(url, true);
|
|
299
|
+
if (jsonOutput) {
|
|
300
|
+
console.log(JSON.stringify({ success: true, ...response }));
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
console.log((0, colors_1.success)('\n✓ Invitation cancelled successfully\n'));
|
|
304
|
+
if (response.status) {
|
|
305
|
+
console.log((0, colors_1.info)(`Status: ${response.status}`));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
if (jsonOutput) {
|
|
311
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
315
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
316
|
+
console.log('Please run: carto auth login');
|
|
317
|
+
}
|
|
318
|
+
else if (err.message.includes('403')) {
|
|
319
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
320
|
+
console.log('You may not have sufficient permissions to cancel invitations.');
|
|
321
|
+
}
|
|
322
|
+
else if (err.message.includes('404')) {
|
|
323
|
+
console.log((0, colors_1.error)('✗ Invitation not found'));
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log((0, colors_1.error)('✗ Failed to cancel invitation: ' + err.message));
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Helper function to resolve user identifier (email or user_id) to user_id
|
|
334
|
+
*/
|
|
335
|
+
async function resolveUserId(userIdOrEmail, client) {
|
|
336
|
+
// If it's already a user ID format, return it directly
|
|
337
|
+
if (!userIdOrEmail.includes('@')) {
|
|
338
|
+
return { userId: userIdOrEmail, email: '' };
|
|
339
|
+
}
|
|
340
|
+
// It's an email, search for the user
|
|
341
|
+
const searchUrl = `/accounts/users?search=${encodeURIComponent(userIdOrEmail)}`;
|
|
342
|
+
const searchResults = await client.getAccounts(searchUrl, true);
|
|
343
|
+
const users = Array.isArray(searchResults) ? searchResults : (searchResults.data || searchResults.results || []);
|
|
344
|
+
const user = users.find((u) => u.email.toLowerCase() === userIdOrEmail.toLowerCase());
|
|
345
|
+
if (!user) {
|
|
346
|
+
throw new Error(`User not found: ${userIdOrEmail}`);
|
|
347
|
+
}
|
|
348
|
+
return { userId: user.user_id, email: user.email };
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Delete a user from the organization
|
|
352
|
+
*/
|
|
353
|
+
async function usersDelete(userIdOrEmail, receiverUserIdOrEmail, apiToken, baseUrl, jsonOutput, debug = false, profile) {
|
|
354
|
+
try {
|
|
355
|
+
const client = await api_1.ApiClient.create(apiToken, baseUrl, debug, profile);
|
|
356
|
+
// Resolve both user identifiers to user IDs
|
|
357
|
+
const userToDelete = await resolveUserId(userIdOrEmail, client);
|
|
358
|
+
const receiverUser = await resolveUserId(receiverUserIdOrEmail, client);
|
|
359
|
+
// URL encode the user IDs
|
|
360
|
+
const encodedUserId = encodeURIComponent(userToDelete.userId);
|
|
361
|
+
const encodedReceiverUserId = encodeURIComponent(receiverUser.userId);
|
|
362
|
+
const url = `/users/${encodedUserId}?resourcesReceiverUserId=${encodedReceiverUserId}`;
|
|
363
|
+
const response = await client.deleteAccounts(url, true);
|
|
364
|
+
if (jsonOutput) {
|
|
365
|
+
console.log(JSON.stringify({
|
|
366
|
+
success: true,
|
|
367
|
+
deletedUserId: userToDelete.userId,
|
|
368
|
+
deletedUserEmail: userToDelete.email || userIdOrEmail,
|
|
369
|
+
receiverUserId: receiverUser.userId,
|
|
370
|
+
receiverUserEmail: receiverUser.email || receiverUserIdOrEmail,
|
|
371
|
+
...response
|
|
372
|
+
}));
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
console.log((0, colors_1.success)('\n✓ User deleted successfully\n'));
|
|
376
|
+
console.log((0, colors_1.info)(`Deleted user: ${userToDelete.email || userToDelete.userId}`));
|
|
377
|
+
console.log((0, colors_1.info)(`Resources transferred to: ${receiverUser.email || receiverUser.userId}`));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
catch (err) {
|
|
381
|
+
if (jsonOutput) {
|
|
382
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
386
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
387
|
+
console.log('Please run: carto auth login');
|
|
388
|
+
}
|
|
389
|
+
else if (err.message.includes('403')) {
|
|
390
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
391
|
+
console.log('You may not have sufficient permissions to delete users.');
|
|
392
|
+
}
|
|
393
|
+
else if (err.message.includes('404') || err.message.includes('User not found')) {
|
|
394
|
+
console.log((0, colors_1.error)('✗ User not found: ' + err.message));
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
console.log((0, colors_1.error)('✗ Failed to delete user: ' + err.message));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* List pending invitations
|
|
405
|
+
*/
|
|
406
|
+
async function usersInvitations(token, baseUrl, jsonOutput, debug = false, profile) {
|
|
407
|
+
try {
|
|
408
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
409
|
+
const url = `/accounts/invitations/in-progress`;
|
|
410
|
+
const invitations = await client.getAccounts(url, true);
|
|
411
|
+
if (jsonOutput) {
|
|
412
|
+
console.log(JSON.stringify(invitations));
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
const invitationList = invitations.invitations || [];
|
|
416
|
+
if (invitationList.length === 0) {
|
|
417
|
+
console.log((0, colors_1.info)('\nNo pending invitations'));
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
console.log((0, colors_1.bold)(`\nPending Invitations (${invitationList.length}):\n`));
|
|
421
|
+
invitationList.forEach((invitation) => {
|
|
422
|
+
console.log((0, colors_1.bold)('Email: ') + invitation.recipient);
|
|
423
|
+
if (invitation.targetRole) {
|
|
424
|
+
console.log(' Role: ' + invitation.targetRole);
|
|
425
|
+
}
|
|
426
|
+
if (invitation.requestedAt) {
|
|
427
|
+
console.log(' Sent: ' + new Date(invitation.requestedAt).toLocaleString());
|
|
428
|
+
}
|
|
429
|
+
if (invitation.status) {
|
|
430
|
+
console.log(' Status: ' + invitation.status);
|
|
431
|
+
}
|
|
432
|
+
if (invitation.expired !== undefined) {
|
|
433
|
+
console.log(' Expired: ' + (invitation.expired ? 'Yes' : 'No'));
|
|
434
|
+
}
|
|
435
|
+
console.log('');
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch (err) {
|
|
441
|
+
if (jsonOutput) {
|
|
442
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
446
|
+
console.log((0, colors_1.error)('✗ Authentication required'));
|
|
447
|
+
console.log('Please run: carto auth login');
|
|
448
|
+
}
|
|
449
|
+
else if (err.message.includes('403')) {
|
|
450
|
+
console.log((0, colors_1.error)('✗ Access denied'));
|
|
451
|
+
console.log('You may not have sufficient permissions to view invitations.');
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
console.log((0, colors_1.error)('✗ Failed to list invitations: ' + err.message));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
process.exit(1);
|
|
458
|
+
}
|
|
459
|
+
}
|