@nestbox-ai/cli 1.0.6 → 1.0.8
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/.nestboxrc +0 -0
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.js +308 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/auth.js +23 -2
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/compute.js +350 -94
- package/dist/commands/compute.js.map +1 -1
- package/dist/commands/document.d.ts +2 -0
- package/dist/commands/document.js +340 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/image.d.ts +2 -0
- package/dist/commands/image.js +147 -0
- package/dist/commands/image.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/agent.d.ts +5 -0
- package/dist/utils/agent.js +192 -0
- package/dist/utils/agent.js.map +1 -0
- package/dist/utils/project.d.ts +15 -0
- package/dist/utils/project.js +76 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/user.d.ts +1 -0
- package/dist/utils/user.js +40 -0
- package/dist/utils/user.js.map +1 -0
- package/nestbox.config.json +9 -0
- package/package.json +12 -3
- package/src/commands/agent.ts +355 -0
- package/src/commands/auth.ts +261 -238
- package/src/commands/compute.ts +407 -115
- package/src/commands/document.ts +472 -0
- package/src/commands/image.ts +155 -0
- package/src/index.ts +6 -0
- package/src/utils/agent.ts +170 -0
- package/src/utils/project.ts +81 -0
- package/src/utils/user.ts +28 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import { exec } from "child_process";
|
|
7
|
+
import AdmZip from "adm-zip";
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
|
|
13
|
+
export async function findProjectRoot(startDir = process.cwd()) {
|
|
14
|
+
let currentDir = startDir;
|
|
15
|
+
|
|
16
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
17
|
+
const nestboxConfigPath = path.join(currentDir, 'nestbox.config.json');
|
|
18
|
+
const packageJsonPath = path.join(currentDir, 'package.json');
|
|
19
|
+
|
|
20
|
+
if (fs.existsSync(nestboxConfigPath) || fs.existsSync(packageJsonPath)) {
|
|
21
|
+
return currentDir;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
currentDir = path.dirname(currentDir);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return startDir; // Fallback to current directory if no root markers found
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Function to load and parse nestbox.config.json if it exists
|
|
31
|
+
export function loadNestboxConfig(projectRoot: any) {
|
|
32
|
+
const configPath = path.join(projectRoot, 'nestbox.config.json');
|
|
33
|
+
|
|
34
|
+
if (fs.existsSync(configPath)) {
|
|
35
|
+
try {
|
|
36
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
37
|
+
return JSON.parse(configContent);
|
|
38
|
+
} catch (error: any) {
|
|
39
|
+
console.warn(chalk.yellow(`Warning: Error parsing nestbox.config.json: ${error.message}`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Function to detect if a directory contains TypeScript files
|
|
47
|
+
export function isTypeScriptProject(directoryPath: any) {
|
|
48
|
+
// Check for tsconfig.json
|
|
49
|
+
if (fs.existsSync(path.join(directoryPath, 'tsconfig.json'))) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check for .ts files
|
|
54
|
+
try {
|
|
55
|
+
const files = fs.readdirSync(directoryPath);
|
|
56
|
+
return files.some(file => file.endsWith('.ts') || file.endsWith('.tsx'));
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function runPredeployScripts(scripts: any, projectRoot: any) {
|
|
63
|
+
if (!scripts || !Array.isArray(scripts) || scripts.length === 0) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const spinner = ora('Running predeploy scripts...').start();
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
for (const script of scripts) {
|
|
71
|
+
spinner.text = `Running: ${script}`;
|
|
72
|
+
|
|
73
|
+
// Make sure we're running in the correct directory
|
|
74
|
+
await execAsync(script, {
|
|
75
|
+
cwd: projectRoot,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
spinner.succeed('Predeploy scripts completed successfully');
|
|
79
|
+
} catch (error: any) {
|
|
80
|
+
spinner.fail(`Predeploy script failed: ${error.message}`);
|
|
81
|
+
throw new Error(`Predeploy failed: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Function to create zip from directory excluding node_modules
|
|
86
|
+
// export function createZipFromDirectory(dirPath: any, excludePatterns = ['node_modules']) {
|
|
87
|
+
// const dirName = path.basename(dirPath);
|
|
88
|
+
// const zipFilePath = path.join(os.tmpdir(), `${dirName}_${Date.now()}.zip`);
|
|
89
|
+
|
|
90
|
+
// const zip = new AdmZip();
|
|
91
|
+
|
|
92
|
+
// // Function to recursively add files to zip
|
|
93
|
+
// function addFilesToZip(currentPath: any, relativePath = '') {
|
|
94
|
+
// const items = fs.readdirSync(currentPath);
|
|
95
|
+
|
|
96
|
+
// for (const item of items) {
|
|
97
|
+
// const itemPath = path.join(currentPath, item);
|
|
98
|
+
// const itemRelativePath = path.join(relativePath, item);
|
|
99
|
+
|
|
100
|
+
// // Check if item should be excluded
|
|
101
|
+
// if (excludePatterns.some(pattern =>
|
|
102
|
+
// typeof pattern === 'string' ? itemRelativePath === pattern || item === pattern :
|
|
103
|
+
// pattern.test(itemRelativePath)
|
|
104
|
+
// )) {
|
|
105
|
+
// continue;
|
|
106
|
+
// }
|
|
107
|
+
|
|
108
|
+
// const stats = fs.statSync(itemPath);
|
|
109
|
+
|
|
110
|
+
// if (stats.isDirectory()) {
|
|
111
|
+
// addFilesToZip(itemPath, itemRelativePath);
|
|
112
|
+
// } else {
|
|
113
|
+
// zip.addLocalFile(itemPath, path.dirname(itemRelativePath));
|
|
114
|
+
// }
|
|
115
|
+
// }
|
|
116
|
+
// }
|
|
117
|
+
|
|
118
|
+
// addFilesToZip(dirPath);
|
|
119
|
+
// zip.writeZip(zipFilePath);
|
|
120
|
+
|
|
121
|
+
// return zipFilePath;
|
|
122
|
+
// }
|
|
123
|
+
|
|
124
|
+
export function createZipFromDirectory(dirPath: any, excludePatterns = ['node_modules', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock']) {
|
|
125
|
+
const dirName = path.basename(dirPath);
|
|
126
|
+
const timestamp = Date.now();
|
|
127
|
+
|
|
128
|
+
// Create zip in temp directory
|
|
129
|
+
const tempZipFilePath = path.join(os.tmpdir(), `${dirName}_${timestamp}.zip`);
|
|
130
|
+
|
|
131
|
+
// Create zip in Downloads folder (Mac)
|
|
132
|
+
const downloadsPath = path.join(os.homedir(), 'Downloads');
|
|
133
|
+
const downloadsZipFilePath = path.join(downloadsPath, `${dirName}_${timestamp}.zip`);
|
|
134
|
+
|
|
135
|
+
const zip = new AdmZip();
|
|
136
|
+
|
|
137
|
+
// Function to recursively add files to zip
|
|
138
|
+
function addFilesToZip(currentPath: any, relativePath = '') {
|
|
139
|
+
const items = fs.readdirSync(currentPath);
|
|
140
|
+
|
|
141
|
+
for (const item of items) {
|
|
142
|
+
const itemPath = path.join(currentPath, item);
|
|
143
|
+
const itemRelativePath = path.join(relativePath, item);
|
|
144
|
+
|
|
145
|
+
// Check if item should be excluded
|
|
146
|
+
if (excludePatterns.some((pattern: any) =>
|
|
147
|
+
typeof pattern === 'string' ? itemRelativePath === pattern || item === pattern :
|
|
148
|
+
pattern.test(itemRelativePath)
|
|
149
|
+
)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const stats = fs.statSync(itemPath);
|
|
154
|
+
|
|
155
|
+
if (stats.isDirectory()) {
|
|
156
|
+
addFilesToZip(itemPath, itemRelativePath);
|
|
157
|
+
} else {
|
|
158
|
+
zip.addLocalFile(itemPath, path.dirname(itemRelativePath));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
addFilesToZip(dirPath);
|
|
164
|
+
|
|
165
|
+
// Write zip to temp directory (for upload)
|
|
166
|
+
zip.writeZip(tempZipFilePath);
|
|
167
|
+
|
|
168
|
+
// Return the temp path for upload
|
|
169
|
+
return tempZipFilePath;
|
|
170
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ProjectsApi } from "@nestbox-ai/admin";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { readNestboxConfig } from "../commands/projects";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
interface ProjectInfo {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface CommandOptions {
|
|
12
|
+
instance: string;
|
|
13
|
+
project?: string;
|
|
14
|
+
collection?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
metadata?: string;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function resolveProject(projectsApi: ProjectsApi, options: CommandOptions): Promise<ProjectInfo> {
|
|
21
|
+
const spinner = ora('Resolving project...').start();
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const projectsResponse = await projectsApi.projectControllerGetAllProjects();
|
|
25
|
+
const allProjects = projectsResponse.data?.data?.projects;
|
|
26
|
+
|
|
27
|
+
if (!allProjects || allProjects.length === 0) {
|
|
28
|
+
spinner.fail('No projects found.');
|
|
29
|
+
throw new Error('No projects found');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let projectId = options.project;
|
|
33
|
+
let projectName = '';
|
|
34
|
+
|
|
35
|
+
if (projectId) {
|
|
36
|
+
const byId = allProjects.find((p) => p.id === projectId);
|
|
37
|
+
const byName = allProjects.find((p) => p.name === projectId);
|
|
38
|
+
|
|
39
|
+
if (byId) {
|
|
40
|
+
projectName = byId.name;
|
|
41
|
+
projectId = byId.id;
|
|
42
|
+
} else if (byName) {
|
|
43
|
+
projectName = byName.name;
|
|
44
|
+
projectId = byName.id;
|
|
45
|
+
} else {
|
|
46
|
+
spinner.fail(`Project not found with ID or name: ${projectId}`);
|
|
47
|
+
throw new Error(`Project not found with ID or name: ${projectId}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
spinner.succeed(`Using project: ${projectName} (ID: ${projectId})`);
|
|
51
|
+
} else {
|
|
52
|
+
const config = readNestboxConfig();
|
|
53
|
+
const defaultProjectName = config.projects?.default;
|
|
54
|
+
|
|
55
|
+
if (!defaultProjectName) {
|
|
56
|
+
spinner.fail('No project specified and no default project set. Please provide a project ID or set a default project.');
|
|
57
|
+
throw new Error('No project specified and no default project set');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const defaultProject = allProjects.find((p) => p.name === defaultProjectName);
|
|
61
|
+
|
|
62
|
+
if (!defaultProject) {
|
|
63
|
+
spinner.fail(`Default project "${defaultProjectName}" not found.`);
|
|
64
|
+
throw new Error(`Default project "${defaultProjectName}" not found.`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
projectId = defaultProject.id;
|
|
68
|
+
projectName = defaultProject.name;
|
|
69
|
+
spinner.succeed(`Using default project: ${projectName} (ID: ${projectId})`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { id: projectId, name: projectName };
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (!spinner.isSpinning) {
|
|
75
|
+
// If spinner was already stopped with fail, we don't need to fail it again
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
spinner.fail('Failed to resolve project');
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { getAuthToken } from "./auth";
|
|
3
|
+
|
|
4
|
+
export async function userData() {
|
|
5
|
+
try {
|
|
6
|
+
const authData = getAuthToken();
|
|
7
|
+
|
|
8
|
+
if (!authData || !authData.serverUrl || !authData.token) {
|
|
9
|
+
throw new Error("No authentication data found. Please login first.");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const response = await axios.get(
|
|
13
|
+
`${authData.serverUrl}/user/me`,
|
|
14
|
+
{
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `${authData.token}`,
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return response.data;
|
|
22
|
+
} catch (error: any) {
|
|
23
|
+
console.error("Error fetching user data:", error.message || "Unknown error");
|
|
24
|
+
if (error.response) {
|
|
25
|
+
}
|
|
26
|
+
throw error; // Rethrow to allow caller to handle the error
|
|
27
|
+
}
|
|
28
|
+
}
|