@orcapt/cli 1.0.0
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/LICENSE +22 -0
- package/QUICK_START.md +241 -0
- package/README.md +949 -0
- package/bin/orca.js +406 -0
- package/package.json +58 -0
- package/src/commands/db.js +248 -0
- package/src/commands/fetch-doc.js +220 -0
- package/src/commands/kickstart-node.js +431 -0
- package/src/commands/kickstart-python.js +360 -0
- package/src/commands/lambda.js +736 -0
- package/src/commands/login.js +277 -0
- package/src/commands/storage.js +911 -0
- package/src/commands/ui.js +286 -0
- package/src/config.js +62 -0
- package/src/utils/docker-helper.js +357 -0
- package/src/utils/index.js +349 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orca Database Commands
|
|
3
|
+
* Manage PostgreSQL databases via Orca Deploy API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const ora = require('ora');
|
|
8
|
+
const https = require('https');
|
|
9
|
+
const http = require('http');
|
|
10
|
+
const { getCredentials } = require('./login');
|
|
11
|
+
const { API_BASE_URL, API_ENDPOINTS } = require('../config');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Make API request to Orca Deploy API
|
|
15
|
+
*/
|
|
16
|
+
function makeApiRequest(method, path, credentials) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const url = new URL(path, API_BASE_URL);
|
|
19
|
+
const isHttps = url.protocol === 'https:';
|
|
20
|
+
const httpModule = isHttps ? https : http;
|
|
21
|
+
|
|
22
|
+
const options = {
|
|
23
|
+
hostname: url.hostname,
|
|
24
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
25
|
+
path: url.pathname,
|
|
26
|
+
method: method,
|
|
27
|
+
headers: {
|
|
28
|
+
'x-workspace': credentials.workspace,
|
|
29
|
+
'x-token': credentials.token,
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
'x-mode' : credentials.mode
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const req = httpModule.request(options, (res) => {
|
|
36
|
+
let data = '';
|
|
37
|
+
|
|
38
|
+
res.on('data', (chunk) => {
|
|
39
|
+
data += chunk;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
res.on('end', () => {
|
|
43
|
+
try {
|
|
44
|
+
const response = JSON.parse(data);
|
|
45
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
46
|
+
resolve(response);
|
|
47
|
+
} else {
|
|
48
|
+
reject({ statusCode: res.statusCode, response });
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
reject(new Error(`Invalid response: ${data}`));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
req.on('error', (error) => {
|
|
57
|
+
reject(error);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
req.end();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* DB Create Command - Create a new PostgreSQL database
|
|
66
|
+
*/
|
|
67
|
+
async function dbCreate(options) {
|
|
68
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
69
|
+
console.log(chalk.cyan('šļø Creating PostgreSQL Database'));
|
|
70
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
71
|
+
|
|
72
|
+
// Get credentials from login
|
|
73
|
+
const credentials = getCredentials();
|
|
74
|
+
if (!credentials) {
|
|
75
|
+
console.log(chalk.red('ā Not authenticated'));
|
|
76
|
+
console.log(chalk.cyan('Please run:'), chalk.yellow('orca login'), chalk.cyan('first\n'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log(chalk.white('Workspace:'), chalk.yellow(credentials.workspace));
|
|
81
|
+
console.log(chalk.white('API: '), chalk.yellow(API_BASE_URL));
|
|
82
|
+
|
|
83
|
+
const spinner = ora('Creating database...').start();
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Hybrid DB API endpoint: creates/uses workspace DB and creates a schema
|
|
87
|
+
const response = await makeApiRequest('POST', API_ENDPOINTS.DB_CREATE, credentials);
|
|
88
|
+
|
|
89
|
+
spinner.succeed(chalk.green('Database created successfully!'));
|
|
90
|
+
|
|
91
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
92
|
+
console.log(chalk.green('ā Database Ready'));
|
|
93
|
+
console.log(chalk.cyan('============================================================'));
|
|
94
|
+
// Show actual DB and schema
|
|
95
|
+
console.log(chalk.white('Database: '), chalk.yellow(response.database_name));
|
|
96
|
+
console.log(chalk.white('Schema: '), chalk.yellow(response.schema_name));
|
|
97
|
+
console.log(chalk.white('Username: '), chalk.yellow(response.username));
|
|
98
|
+
console.log(chalk.white('Password: '), chalk.yellow(response.password));
|
|
99
|
+
console.log(chalk.white('Workspace: '), chalk.yellow(response.workspace_name));
|
|
100
|
+
|
|
101
|
+
console.log(chalk.cyan('\nš Connection String:'));
|
|
102
|
+
// Use the connection string from the response if available
|
|
103
|
+
const connString = response.connection_info?.connection_string ||
|
|
104
|
+
`postgresql://${response.username}:${response.password}@localhost:6432/${response.database_name}?options=-csearch_path%3D${response.schema_name}`;
|
|
105
|
+
console.log(chalk.yellow(` ${connString}`));
|
|
106
|
+
|
|
107
|
+
console.log(chalk.cyan('\nš” Save these credentials - they won\'t be shown again!'));
|
|
108
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
109
|
+
|
|
110
|
+
} catch (error) {
|
|
111
|
+
spinner.fail(chalk.red('Failed to create database'));
|
|
112
|
+
|
|
113
|
+
if (error.statusCode === 401) {
|
|
114
|
+
console.log(chalk.red('\nā Authentication failed'));
|
|
115
|
+
console.log(chalk.yellow('Your session may have expired. Please run:'), chalk.white('orca login\n'));
|
|
116
|
+
} else if (error.response && error.response.detail) {
|
|
117
|
+
console.log(chalk.red(`\nā ${error.response.detail}\n`));
|
|
118
|
+
} else {
|
|
119
|
+
console.log(chalk.red(`\nā ${error.message}\n`));
|
|
120
|
+
}
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* DB List Command - List all databases for workspace
|
|
127
|
+
*/
|
|
128
|
+
async function dbList() {
|
|
129
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
130
|
+
console.log(chalk.cyan('š Listing Databases'));
|
|
131
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
132
|
+
|
|
133
|
+
// Get credentials from login
|
|
134
|
+
const credentials = getCredentials();
|
|
135
|
+
if (!credentials) {
|
|
136
|
+
console.log(chalk.red('ā Not authenticated'));
|
|
137
|
+
console.log(chalk.cyan('Please run:'), chalk.yellow('orca login'), chalk.cyan('first\n'));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log(chalk.white('Workspace:'), chalk.yellow(credentials.workspace));
|
|
142
|
+
|
|
143
|
+
const spinner = ora('Fetching databases...').start();
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
// DB API endpoint (returns list of { database_name, schema_name })
|
|
147
|
+
const response = await makeApiRequest('GET', API_ENDPOINTS.DB_LIST, credentials);
|
|
148
|
+
|
|
149
|
+
spinner.succeed(chalk.green('Databases retrieved'));
|
|
150
|
+
|
|
151
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
152
|
+
|
|
153
|
+
if (response.count === 0) {
|
|
154
|
+
console.log(chalk.yellow('No databases found'));
|
|
155
|
+
console.log(chalk.cyan('\nCreate one with:'), chalk.white('orca db create --postgres'));
|
|
156
|
+
} else {
|
|
157
|
+
console.log(chalk.green(`ā Found ${response.count} database${response.count > 1 ? 's' : ''}`));
|
|
158
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
159
|
+
|
|
160
|
+
// Show schemas as databases to avoid confusion
|
|
161
|
+
const items = response.databases || response.schemas || [];
|
|
162
|
+
items.forEach((item, index) => {
|
|
163
|
+
const name = typeof item === 'string' ? item : (item.schema_name || item.database_name);
|
|
164
|
+
console.log(chalk.white(` ${index + 1}. ${name}`));
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
169
|
+
|
|
170
|
+
} catch (error) {
|
|
171
|
+
spinner.fail(chalk.red('Failed to list databases'));
|
|
172
|
+
|
|
173
|
+
if (error.statusCode === 401) {
|
|
174
|
+
console.log(chalk.red('\nā Authentication failed'));
|
|
175
|
+
console.log(chalk.yellow('Your session may have expired. Please run:'), chalk.white('orca login\n'));
|
|
176
|
+
} else if (error.response && error.response.detail) {
|
|
177
|
+
console.log(chalk.red(`\nā ${error.response.detail}\n`));
|
|
178
|
+
} else {
|
|
179
|
+
console.log(chalk.red(`\nā ${error.message}\n`));
|
|
180
|
+
}
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* DB Remove Command - Delete a database
|
|
187
|
+
*/
|
|
188
|
+
async function dbRemove(databaseName) {
|
|
189
|
+
if (!databaseName) {
|
|
190
|
+
console.log(chalk.red('\nā Database name is required'));
|
|
191
|
+
console.log(chalk.cyan('Usage:'), chalk.white('orca db remove <database-name>\n'));
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
196
|
+
console.log(chalk.cyan('šļø Removing Database'));
|
|
197
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
198
|
+
|
|
199
|
+
// Get credentials from login
|
|
200
|
+
const credentials = getCredentials();
|
|
201
|
+
if (!credentials) {
|
|
202
|
+
console.log(chalk.red('ā Not authenticated'));
|
|
203
|
+
console.log(chalk.cyan('Please run:'), chalk.yellow('orca login'), chalk.cyan('first\n'));
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log(chalk.white('Database: '), chalk.yellow(databaseName));
|
|
208
|
+
console.log(chalk.white('Workspace:'), chalk.yellow(credentials.workspace));
|
|
209
|
+
|
|
210
|
+
const spinner = ora('Deleting database...').start();
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
// Delete a single schema under the workspace database
|
|
214
|
+
const response = await makeApiRequest('DELETE', `${API_ENDPOINTS.DB_DELETE}/${databaseName}`, credentials);
|
|
215
|
+
|
|
216
|
+
spinner.succeed(chalk.green('Database deleted successfully!'));
|
|
217
|
+
|
|
218
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
219
|
+
console.log(chalk.green('ā Database Removed'));
|
|
220
|
+
console.log(chalk.cyan('============================================================'));
|
|
221
|
+
// Present schema as database name
|
|
222
|
+
console.log(chalk.white('Database: '), chalk.yellow(response.schema_name || databaseName));
|
|
223
|
+
console.log(chalk.white('Workspace: '), chalk.yellow(response.workspace_name));
|
|
224
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
225
|
+
|
|
226
|
+
} catch (error) {
|
|
227
|
+
spinner.fail(chalk.red('Failed to delete database'));
|
|
228
|
+
|
|
229
|
+
if (error.statusCode === 401) {
|
|
230
|
+
console.log(chalk.red('\nā Authentication failed'));
|
|
231
|
+
console.log(chalk.yellow('Your session may have expired. Please run:'), chalk.white('orca login\n'));
|
|
232
|
+
} else if (error.statusCode === 404) {
|
|
233
|
+
console.log(chalk.red(`\nā Database '${databaseName}' not found or doesn't belong to your workspace\n`));
|
|
234
|
+
} else if (error.response && error.response.detail) {
|
|
235
|
+
console.log(chalk.red(`\nā ${error.response.detail}\n`));
|
|
236
|
+
} else {
|
|
237
|
+
console.log(chalk.red(`\nā ${error.message}\n`));
|
|
238
|
+
}
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = {
|
|
244
|
+
dbCreate,
|
|
245
|
+
dbList,
|
|
246
|
+
dbRemove
|
|
247
|
+
};
|
|
248
|
+
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch Documentation Command
|
|
3
|
+
* Downloads Orca SDK documentation based on project type
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs').promises;
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const inquirer = require('inquirer');
|
|
10
|
+
const ora = require('ora');
|
|
11
|
+
const https = require('https');
|
|
12
|
+
const { DOCS_URLS } = require('../config');
|
|
13
|
+
|
|
14
|
+
// Map project types to config keys
|
|
15
|
+
const DOCS_MAP = {
|
|
16
|
+
python: DOCS_URLS.PYTHON,
|
|
17
|
+
nodejs: DOCS_URLS.NODEJS
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Detect project type based on files in current directory
|
|
22
|
+
* @returns {Promise<string|null>} 'python', 'nodejs', or null
|
|
23
|
+
*/
|
|
24
|
+
async function detectProjectType() {
|
|
25
|
+
try {
|
|
26
|
+
const files = await fs.readdir(process.cwd());
|
|
27
|
+
|
|
28
|
+
// Check for Python project indicators
|
|
29
|
+
const hasPythonFiles = files.some(file =>
|
|
30
|
+
file === 'requirements.txt' ||
|
|
31
|
+
file === 'setup.py' ||
|
|
32
|
+
file === 'pyproject.toml' ||
|
|
33
|
+
file === 'Pipfile'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (hasPythonFiles) {
|
|
37
|
+
return 'python';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check for Node.js project indicators
|
|
41
|
+
const hasNodeFiles = files.some(file =>
|
|
42
|
+
file === 'package.json' ||
|
|
43
|
+
file === 'package-lock.json' ||
|
|
44
|
+
file === 'yarn.lock'
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (hasNodeFiles) {
|
|
48
|
+
return 'nodejs';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if we're in a project root directory
|
|
59
|
+
* @returns {Promise<{isRoot: boolean, detectedType: string|null}>}
|
|
60
|
+
*/
|
|
61
|
+
async function checkProjectRoot() {
|
|
62
|
+
const detectedType = await detectProjectType();
|
|
63
|
+
return {
|
|
64
|
+
isRoot: detectedType !== null,
|
|
65
|
+
detectedType
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Download file from URL
|
|
71
|
+
* @param {string} url - URL to download from
|
|
72
|
+
* @param {string} destPath - Destination path
|
|
73
|
+
* @returns {Promise<void>}
|
|
74
|
+
*/
|
|
75
|
+
function downloadFile(url, destPath) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
https.get(url, (response) => {
|
|
78
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
79
|
+
// Handle redirects
|
|
80
|
+
downloadFile(response.headers.location, destPath)
|
|
81
|
+
.then(resolve)
|
|
82
|
+
.catch(reject);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (response.statusCode !== 200) {
|
|
87
|
+
reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let data = '';
|
|
92
|
+
response.on('data', (chunk) => {
|
|
93
|
+
data += chunk;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
response.on('end', async () => {
|
|
97
|
+
try {
|
|
98
|
+
await fs.writeFile(destPath, data, 'utf8');
|
|
99
|
+
resolve();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
reject(error);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}).on('error', (error) => {
|
|
105
|
+
reject(error);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Ensure docs directory exists
|
|
112
|
+
* @returns {Promise<string>} Path to docs directory
|
|
113
|
+
*/
|
|
114
|
+
async function ensureDocsDirectory() {
|
|
115
|
+
const docsPath = path.join(process.cwd(), 'docs');
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await fs.access(docsPath);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
// Directory doesn't exist, create it
|
|
121
|
+
await fs.mkdir(docsPath, { recursive: true });
|
|
122
|
+
console.log(chalk.green('ā Created docs directory'));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return docsPath;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Download documentation for a specific type
|
|
130
|
+
* @param {string} type - 'python' or 'nodejs'
|
|
131
|
+
* @returns {Promise<void>}
|
|
132
|
+
*/
|
|
133
|
+
async function downloadDocumentation(type) {
|
|
134
|
+
const spinner = ora(`Downloading Orca ${type === 'python' ? 'Python' : 'Node.js'} SDK documentation...`).start();
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const docsPath = await ensureDocsDirectory();
|
|
138
|
+
const fileName = type === 'python' ? 'ORCA_PYTHON_SDK.md' : 'ORCA_NODEJS_SDK.md';
|
|
139
|
+
const filePath = path.join(docsPath, fileName);
|
|
140
|
+
|
|
141
|
+
await downloadFile(DOCS_MAP[type], filePath);
|
|
142
|
+
|
|
143
|
+
spinner.succeed(chalk.green('Documentation downloaded successfully!'));
|
|
144
|
+
|
|
145
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
146
|
+
console.log(chalk.green('ā Documentation Ready'));
|
|
147
|
+
console.log(chalk.cyan('============================================================'));
|
|
148
|
+
console.log(chalk.white('š File:'), chalk.yellow(path.relative(process.cwd(), filePath)));
|
|
149
|
+
console.log(chalk.white('š¦ Type:'), chalk.yellow(type === 'python' ? 'Python SDK' : 'Node.js SDK'));
|
|
150
|
+
console.log(chalk.white('š Location:'), chalk.yellow(docsPath));
|
|
151
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
152
|
+
|
|
153
|
+
return filePath;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
spinner.fail(chalk.red('Failed to download documentation'));
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Main fetch-doc command
|
|
162
|
+
*/
|
|
163
|
+
async function fetchDoc() {
|
|
164
|
+
try {
|
|
165
|
+
console.log(chalk.cyan('\n============================================================'));
|
|
166
|
+
console.log(chalk.cyan('š Orca - Fetch Documentation'));
|
|
167
|
+
console.log(chalk.cyan('============================================================\n'));
|
|
168
|
+
|
|
169
|
+
// Check if we're in a project root
|
|
170
|
+
const { isRoot, detectedType } = await checkProjectRoot();
|
|
171
|
+
|
|
172
|
+
let selectedType;
|
|
173
|
+
|
|
174
|
+
if (!isRoot) {
|
|
175
|
+
// Not in project root - show warning and ask user
|
|
176
|
+
console.log(chalk.yellow('ā Warning: Could not detect project type'));
|
|
177
|
+
console.log(chalk.white('We recommend running this command in the root directory of your project.'));
|
|
178
|
+
console.log(chalk.gray('(Looking for requirements.txt, package.json, etc.)\n'));
|
|
179
|
+
|
|
180
|
+
const { choice } = await inquirer.prompt([
|
|
181
|
+
{
|
|
182
|
+
type: 'list',
|
|
183
|
+
name: 'choice',
|
|
184
|
+
message: 'Which documentation would you like to download?',
|
|
185
|
+
choices: [
|
|
186
|
+
{ name: 'š Python SDK Documentation', value: 'python' },
|
|
187
|
+
{ name: 'š¦ Node.js SDK Documentation', value: 'nodejs' },
|
|
188
|
+
{ name: 'ā Skip, cancel', value: 'none' }
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
]);
|
|
192
|
+
|
|
193
|
+
if (choice === 'none') {
|
|
194
|
+
console.log(chalk.yellow('\nā Cancelled\n'));
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
selectedType = choice;
|
|
199
|
+
} else {
|
|
200
|
+
// In project root - auto-detect
|
|
201
|
+
console.log(chalk.green('ā Project detected:'), chalk.yellow(detectedType === 'python' ? 'Python' : 'Node.js'));
|
|
202
|
+
console.log();
|
|
203
|
+
|
|
204
|
+
selectedType = detectedType;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Download documentation
|
|
208
|
+
await downloadDocumentation(selectedType);
|
|
209
|
+
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.log(chalk.red(`\nā Error: ${error.message}\n`));
|
|
212
|
+
if (process.env.DEBUG) {
|
|
213
|
+
console.error(error);
|
|
214
|
+
}
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = fetchDoc;
|
|
220
|
+
|