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,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectionsList = connectionsList;
|
|
4
|
+
exports.connectionsGet = connectionsGet;
|
|
5
|
+
exports.connectionsCreate = connectionsCreate;
|
|
6
|
+
exports.connectionsUpdate = connectionsUpdate;
|
|
7
|
+
exports.connectionsDelete = connectionsDelete;
|
|
8
|
+
exports.connectionsBrowse = connectionsBrowse;
|
|
9
|
+
exports.connectionsDescribe = connectionsDescribe;
|
|
10
|
+
const api_1 = require("../api");
|
|
11
|
+
const colors_1 = require("../colors");
|
|
12
|
+
const prompt_1 = require("../prompt");
|
|
13
|
+
async function connectionsList(options, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
14
|
+
try {
|
|
15
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
16
|
+
let result;
|
|
17
|
+
if (options.all || options.page || options.pageSize || options.search) {
|
|
18
|
+
// Fetch with parameters - workspace API doesn't support pagination the same way
|
|
19
|
+
// For now, fetch from workspace API without pagination
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
if (options.search)
|
|
22
|
+
params.append('search', options.search);
|
|
23
|
+
const queryString = params.toString();
|
|
24
|
+
const path = `/connections${queryString ? '?' + queryString : ''}`;
|
|
25
|
+
result = await client.getWorkspace(path);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Fetch default (no pagination)
|
|
29
|
+
result = await client.getWorkspace('/connections');
|
|
30
|
+
}
|
|
31
|
+
if (jsonOutput) {
|
|
32
|
+
console.log(JSON.stringify(result));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const connections = Array.isArray(result) ? result : (result.data || result.results || result);
|
|
36
|
+
const total = result.total || connections.length;
|
|
37
|
+
console.log((0, colors_1.bold)(`\nConnections (${total}):\n`));
|
|
38
|
+
connections.forEach((conn) => {
|
|
39
|
+
console.log((0, colors_1.bold)('ID: ') + conn.id);
|
|
40
|
+
console.log(' Name: ' + conn.name);
|
|
41
|
+
console.log(' Type: ' + (conn.provider_id || conn.type));
|
|
42
|
+
console.log(' Privacy: ' + (conn.privacy || 'unknown'));
|
|
43
|
+
// Show sharing scope if available
|
|
44
|
+
if (conn.sharingScope) {
|
|
45
|
+
console.log(' Sharing: ' + conn.sharingScope);
|
|
46
|
+
}
|
|
47
|
+
// Show owner email from workspace API
|
|
48
|
+
if (conn.ownerEmail) {
|
|
49
|
+
console.log(' Owner: ' + conn.ownerEmail);
|
|
50
|
+
}
|
|
51
|
+
else if (conn.config?.credentials?.client_email) {
|
|
52
|
+
console.log(' Owner: ' + conn.config.credentials.client_email);
|
|
53
|
+
}
|
|
54
|
+
else if (conn.user_id) {
|
|
55
|
+
console.log(' User ID: ' + conn.user_id);
|
|
56
|
+
}
|
|
57
|
+
// Show map count if available
|
|
58
|
+
if (conn.mapcount !== undefined) {
|
|
59
|
+
console.log(' Maps using: ' + conn.mapcount);
|
|
60
|
+
}
|
|
61
|
+
if (conn.description)
|
|
62
|
+
console.log(' Description: ' + conn.description);
|
|
63
|
+
console.log(' Created: ' + new Date(conn.created_at).toLocaleString());
|
|
64
|
+
console.log(' Updated: ' + new Date(conn.updated_at).toLocaleString());
|
|
65
|
+
console.log('');
|
|
66
|
+
});
|
|
67
|
+
if (options.all) {
|
|
68
|
+
console.log((0, colors_1.dim)(`Fetched all ${total} connections`));
|
|
69
|
+
}
|
|
70
|
+
else if (result.total && result.page_size) {
|
|
71
|
+
const totalPages = Math.ceil(result.total / result.page_size);
|
|
72
|
+
console.log((0, colors_1.dim)(`Page ${result.page || 1} of ${totalPages} (use --all to fetch all pages)`));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
if (jsonOutput) {
|
|
78
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
82
|
+
console.log((0, colors_1.error)('β Authentication required'));
|
|
83
|
+
console.log('Please run: carto auth login');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.log((0, colors_1.error)('β Failed to list connections: ' + err.message));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function connectionsGet(connectionId, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
93
|
+
try {
|
|
94
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
95
|
+
const result = await client.getWorkspace(`/connections/${connectionId}`);
|
|
96
|
+
if (jsonOutput) {
|
|
97
|
+
console.log(JSON.stringify(result));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.log((0, colors_1.bold)('\nConnection Details:\n'));
|
|
101
|
+
console.log((0, colors_1.bold)('ID: ') + result.id);
|
|
102
|
+
console.log((0, colors_1.bold)('Name: ') + result.name);
|
|
103
|
+
console.log((0, colors_1.bold)('Type: ') + (result.provider_id || result.type));
|
|
104
|
+
console.log((0, colors_1.bold)('Privacy: ') + (result.privacy || 'unknown'));
|
|
105
|
+
// Show sharing scope if available
|
|
106
|
+
if (result.sharingScope) {
|
|
107
|
+
console.log((0, colors_1.bold)('Sharing: ') + result.sharingScope);
|
|
108
|
+
}
|
|
109
|
+
// Show owner email from workspace API
|
|
110
|
+
if (result.ownerEmail) {
|
|
111
|
+
console.log((0, colors_1.bold)('Owner: ') + result.ownerEmail);
|
|
112
|
+
}
|
|
113
|
+
else if (result.config?.credentials?.client_email) {
|
|
114
|
+
console.log((0, colors_1.bold)('Owner: ') + result.config.credentials.client_email);
|
|
115
|
+
}
|
|
116
|
+
else if (result.user_id) {
|
|
117
|
+
console.log((0, colors_1.bold)('User ID: ') + result.user_id);
|
|
118
|
+
}
|
|
119
|
+
// Show map count if available
|
|
120
|
+
if (result.mapcount !== undefined) {
|
|
121
|
+
console.log((0, colors_1.bold)('Maps using: ') + result.mapcount);
|
|
122
|
+
}
|
|
123
|
+
if (result.description)
|
|
124
|
+
console.log((0, colors_1.bold)('Description: ') + result.description);
|
|
125
|
+
console.log((0, colors_1.bold)('Created: ') + new Date(result.created_at).toLocaleString());
|
|
126
|
+
console.log((0, colors_1.bold)('Updated: ') + new Date(result.updated_at).toLocaleString());
|
|
127
|
+
if (result.parameters) {
|
|
128
|
+
console.log((0, colors_1.bold)('\nParameters:'));
|
|
129
|
+
Object.entries(result.parameters).forEach(([key, value]) => {
|
|
130
|
+
console.log(` ${key}: ${value}`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (jsonOutput) {
|
|
137
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log((0, colors_1.error)('β Failed to get connection: ' + err.message));
|
|
141
|
+
}
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function connectionsCreate(body, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
146
|
+
try {
|
|
147
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
148
|
+
const result = await client.post('/v3/connections', body);
|
|
149
|
+
if (jsonOutput) {
|
|
150
|
+
console.log(JSON.stringify(result));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log((0, colors_1.success)('β Connection created successfully'));
|
|
154
|
+
console.log((0, colors_1.bold)('\nID: ') + result.id);
|
|
155
|
+
console.log((0, colors_1.bold)('Name: ') + result.name);
|
|
156
|
+
console.log((0, colors_1.bold)('Type: ') + result.type);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
if (jsonOutput) {
|
|
161
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log((0, colors_1.error)('β Failed to create connection: ' + err.message));
|
|
165
|
+
}
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function connectionsUpdate(connectionId, body, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
170
|
+
try {
|
|
171
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
172
|
+
const result = await client.patch(`/v3/connections/${connectionId}`, body);
|
|
173
|
+
if (jsonOutput) {
|
|
174
|
+
console.log(JSON.stringify(result));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log((0, colors_1.success)('β Connection updated successfully'));
|
|
178
|
+
console.log((0, colors_1.bold)('\nID: ') + result.id);
|
|
179
|
+
console.log((0, colors_1.bold)('Name: ') + result.name);
|
|
180
|
+
console.log((0, colors_1.bold)('Type: ') + result.type);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
if (jsonOutput) {
|
|
185
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log((0, colors_1.error)('β Failed to update connection: ' + err.message));
|
|
189
|
+
}
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async function connectionsDelete(connectionId, token, baseUrl, jsonOutput, debug = false, profile, yes) {
|
|
194
|
+
try {
|
|
195
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
196
|
+
// Skip confirmation if --yes or --json flag is set
|
|
197
|
+
const skipConfirmation = yes || jsonOutput;
|
|
198
|
+
if (!skipConfirmation) {
|
|
199
|
+
// Fetch connection details to show in confirmation prompt
|
|
200
|
+
let connectionDetails;
|
|
201
|
+
try {
|
|
202
|
+
connectionDetails = await client.getWorkspace(`/connections/${connectionId}`);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
// If we can't fetch details, proceed with generic message
|
|
206
|
+
console.log((0, colors_1.warning)('\nβ οΈ Warning: This will permanently delete this connection.'));
|
|
207
|
+
console.log((0, colors_1.warning)(` Connection ID: ${connectionId}`));
|
|
208
|
+
}
|
|
209
|
+
if (connectionDetails) {
|
|
210
|
+
console.log((0, colors_1.warning)('\nβ οΈ Warning: This will permanently delete:'));
|
|
211
|
+
console.log(` Connection: "${connectionDetails.name}"`);
|
|
212
|
+
console.log(` Type: ${connectionDetails.provider_id || connectionDetails.type}`);
|
|
213
|
+
console.log(` ID: ${connectionId}`);
|
|
214
|
+
if (connectionDetails.mapcount !== undefined && connectionDetails.mapcount > 0) {
|
|
215
|
+
console.log((0, colors_1.warning)(` β οΈ This connection is used by ${connectionDetails.mapcount} map(s)`));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
console.log('');
|
|
219
|
+
const confirmed = await (0, prompt_1.promptForConfirmation)("Type 'delete' to confirm: ", 'delete');
|
|
220
|
+
if (!confirmed) {
|
|
221
|
+
console.log('\nDeletion cancelled');
|
|
222
|
+
process.exit(0);
|
|
223
|
+
}
|
|
224
|
+
console.log('');
|
|
225
|
+
}
|
|
226
|
+
await client.delete(`/v3/connections/${connectionId}`);
|
|
227
|
+
if (jsonOutput) {
|
|
228
|
+
console.log(JSON.stringify({ success: true, message: 'Connection deleted successfully', id: connectionId }));
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
console.log((0, colors_1.success)(`β Connection ${connectionId} deleted successfully`));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
if (jsonOutput) {
|
|
236
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.log((0, colors_1.error)('β Failed to delete connection: ' + err.message));
|
|
240
|
+
}
|
|
241
|
+
process.exit(1);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Helper function to resolve connection name to ID
|
|
246
|
+
*/
|
|
247
|
+
async function resolveConnectionId(client, nameOrId) {
|
|
248
|
+
// If it looks like a UUID, return it as-is
|
|
249
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(nameOrId)) {
|
|
250
|
+
return nameOrId;
|
|
251
|
+
}
|
|
252
|
+
// Otherwise, look up by name
|
|
253
|
+
const connections = await client.getWorkspace('/connections');
|
|
254
|
+
const connectionsList = Array.isArray(connections) ? connections : (connections.data || connections.results || []);
|
|
255
|
+
const found = connectionsList.find((c) => c.name === nameOrId);
|
|
256
|
+
if (!found) {
|
|
257
|
+
throw new Error(`Connection "${nameOrId}" not found`);
|
|
258
|
+
}
|
|
259
|
+
return found.id;
|
|
260
|
+
}
|
|
261
|
+
async function connectionsBrowse(connectionName, path, options, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
262
|
+
try {
|
|
263
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
264
|
+
// Resolve connection name to ID
|
|
265
|
+
const connectionId = await resolveConnectionId(client, connectionName);
|
|
266
|
+
// Build the resource path
|
|
267
|
+
let resourcePath = `/connections/${connectionId}/resources/`;
|
|
268
|
+
if (path) {
|
|
269
|
+
// URL encode the path
|
|
270
|
+
resourcePath += encodeURIComponent(path);
|
|
271
|
+
}
|
|
272
|
+
// Add pagination parameters
|
|
273
|
+
const params = new URLSearchParams();
|
|
274
|
+
params.append('pageSize', options.pageSize || '30');
|
|
275
|
+
params.append('page', options.page || '1');
|
|
276
|
+
resourcePath += '?' + params.toString();
|
|
277
|
+
const result = await client.getWorkspace(resourcePath);
|
|
278
|
+
if (jsonOutput) {
|
|
279
|
+
console.log(JSON.stringify(result));
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
const children = result.children || [];
|
|
283
|
+
const type = result.type || 'connection';
|
|
284
|
+
const provider = result.provider || 'unknown';
|
|
285
|
+
console.log((0, colors_1.bold)(`\n${connectionName} (${provider}):`));
|
|
286
|
+
if (path) {
|
|
287
|
+
console.log((0, colors_1.dim)(`Path: ${path}\n`));
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
console.log('');
|
|
291
|
+
}
|
|
292
|
+
if (children.length === 0) {
|
|
293
|
+
console.log((0, colors_1.dim)('No resources found'));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
children.forEach((child) => {
|
|
297
|
+
const icon = child.type === 'project' ? 'π' :
|
|
298
|
+
child.type === 'dataset' ? 'π' :
|
|
299
|
+
child.type === 'table' ? 'π' :
|
|
300
|
+
child.type === 'view' ? 'ποΈ ' : 'β’';
|
|
301
|
+
console.log(`${icon} ${(0, colors_1.bold)(child.name)} ${(0, colors_1.dim)(`(${child.type})`)}`);
|
|
302
|
+
if (child.location) {
|
|
303
|
+
console.log(` Location: ${child.location}`);
|
|
304
|
+
}
|
|
305
|
+
if (child._links?.resources) {
|
|
306
|
+
console.log((0, colors_1.dim)(` Path: ${child.id}`));
|
|
307
|
+
}
|
|
308
|
+
console.log('');
|
|
309
|
+
});
|
|
310
|
+
console.log((0, colors_1.dim)(`Total: ${result.totalChildren || children.length} ${type === 'connection' ? 'projects' : type === 'project' ? 'datasets' : 'resources'}`));
|
|
311
|
+
if (result.totalChildren > children.length) {
|
|
312
|
+
const currentPage = result.page || 1;
|
|
313
|
+
const pageSize = result.pageSize || 30;
|
|
314
|
+
const totalPages = Math.ceil(result.totalChildren / pageSize);
|
|
315
|
+
console.log((0, colors_1.dim)(`Page ${currentPage} of ${totalPages} (use --page <n> to see more)`));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
if (jsonOutput) {
|
|
322
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
326
|
+
console.log((0, colors_1.error)('β Authentication required'));
|
|
327
|
+
console.log('Please run: carto auth login');
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
console.log((0, colors_1.error)('β Failed to browse connection: ' + err.message));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function connectionsDescribe(connectionName, tablePath, token, baseUrl, jsonOutput, debug = false, profile) {
|
|
337
|
+
try {
|
|
338
|
+
const client = await api_1.ApiClient.create(token, baseUrl, debug, profile);
|
|
339
|
+
// Resolve connection name to ID
|
|
340
|
+
const connectionId = await resolveConnectionId(client, connectionName);
|
|
341
|
+
// Build the resource path with type=table to get schema details
|
|
342
|
+
const resourcePath = `/connections/${connectionId}/resources/${encodeURIComponent(tablePath)}?type=table`;
|
|
343
|
+
const result = await client.getWorkspace(resourcePath);
|
|
344
|
+
if (jsonOutput) {
|
|
345
|
+
console.log(JSON.stringify(result));
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
console.log((0, colors_1.bold)('\nTable Details:\n'));
|
|
349
|
+
console.log((0, colors_1.bold)('ID: ') + result.id);
|
|
350
|
+
console.log((0, colors_1.bold)('Name: ') + result.name);
|
|
351
|
+
console.log((0, colors_1.bold)('Type: ') + result.type);
|
|
352
|
+
console.log((0, colors_1.bold)('Provider: ') + result.provider);
|
|
353
|
+
if (result.geomField) {
|
|
354
|
+
console.log((0, colors_1.bold)('Geometry Column: ') + result.geomField);
|
|
355
|
+
}
|
|
356
|
+
if (result.nrows !== undefined) {
|
|
357
|
+
console.log((0, colors_1.bold)('Rows: ') + result.nrows.toLocaleString());
|
|
358
|
+
}
|
|
359
|
+
if (result.size !== undefined) {
|
|
360
|
+
const sizeMB = (result.size / (1024 * 1024)).toFixed(2);
|
|
361
|
+
console.log((0, colors_1.bold)('Size: ') + `${sizeMB} MB`);
|
|
362
|
+
}
|
|
363
|
+
if (result.tableRegion) {
|
|
364
|
+
console.log((0, colors_1.bold)('Region: ') + result.tableRegion);
|
|
365
|
+
}
|
|
366
|
+
if (result.lastModified) {
|
|
367
|
+
console.log((0, colors_1.bold)('Last Modified: ') + new Date(result.lastModified).toLocaleString());
|
|
368
|
+
}
|
|
369
|
+
// Display schema
|
|
370
|
+
if (result.schema && result.schema.length > 0) {
|
|
371
|
+
console.log((0, colors_1.bold)('\nSchema:'));
|
|
372
|
+
console.log('');
|
|
373
|
+
result.schema.forEach((col) => {
|
|
374
|
+
const isGeom = col.name === result.geomField;
|
|
375
|
+
const colName = isGeom ? `${col.name} πΊοΈ` : col.name;
|
|
376
|
+
console.log(` ${(0, colors_1.bold)(colName)}`);
|
|
377
|
+
console.log(` Type: ${col.type}`);
|
|
378
|
+
// Show original type if available
|
|
379
|
+
const originalCol = result.originalSchema?.find((c) => c.name === col.name);
|
|
380
|
+
if (originalCol && originalCol.type !== col.type) {
|
|
381
|
+
console.log((0, colors_1.dim)(` Original: ${originalCol.type}`));
|
|
382
|
+
}
|
|
383
|
+
console.log('');
|
|
384
|
+
});
|
|
385
|
+
console.log((0, colors_1.dim)(`Total columns: ${result.schema.length}`));
|
|
386
|
+
}
|
|
387
|
+
// Display optimization info if available
|
|
388
|
+
if (result.optimization?.actions) {
|
|
389
|
+
console.log((0, colors_1.bold)('\nOptimization:'));
|
|
390
|
+
result.optimization.actions.forEach((action) => {
|
|
391
|
+
const status = action.enabled ? 'β' : 'β';
|
|
392
|
+
console.log(` ${status} ${action.type}`);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
if (jsonOutput) {
|
|
399
|
+
console.log(JSON.stringify({ success: false, error: err.message }));
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
if (err.message.includes('401') || err.message.includes('Token not defined')) {
|
|
403
|
+
console.log((0, colors_1.error)('β Authentication required'));
|
|
404
|
+
console.log('Please run: carto auth login');
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
console.log((0, colors_1.error)('β Failed to describe table: ' + err.message));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
process.exit(1);
|
|
411
|
+
}
|
|
412
|
+
}
|