gufi-cli 0.1.1 → 0.1.3
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/CLAUDE.md +1491 -0
- package/dist/commands/companies.d.ts +26 -0
- package/dist/commands/companies.js +513 -0
- package/dist/commands/login.js +4 -3
- package/dist/commands/logs.d.ts +8 -0
- package/dist/commands/logs.js +153 -0
- package/dist/commands/push.d.ts +2 -2
- package/dist/commands/push.js +4 -3
- package/dist/index.d.ts +17 -7
- package/dist/index.js +64 -8
- package/dist/lib/api.d.ts +1 -0
- package/dist/lib/api.js +42 -5
- package/dist/lib/config.d.ts +4 -1
- package/dist/lib/config.js +13 -1
- package/package.json +15 -3
- package/src/commands/list.ts +0 -51
- package/src/commands/login.ts +0 -124
- package/src/commands/pull.ts +0 -113
- package/src/commands/push.ts +0 -85
- package/src/commands/watch.ts +0 -89
- package/src/index.ts +0 -73
- package/src/lib/api.ts +0 -127
- package/src/lib/config.ts +0 -93
- package/src/lib/sync.ts +0 -236
- package/tsconfig.json +0 -17
package/src/commands/pull.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gufi pull - Download view files from Gufi
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import ora from "ora";
|
|
7
|
-
import { listPackages, listViews, getView } from "../lib/api.js";
|
|
8
|
-
import { pullView } from "../lib/sync.js";
|
|
9
|
-
import { isLoggedIn } from "../lib/config.js";
|
|
10
|
-
|
|
11
|
-
export async function pullCommand(viewIdentifier?: string): Promise<void> {
|
|
12
|
-
if (!isLoggedIn()) {
|
|
13
|
-
console.log(chalk.red("\n ✗ No estás logueado. Usa: gufi login\n"));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
console.log(chalk.magenta("\n 🟣 Gufi Pull\n"));
|
|
18
|
-
|
|
19
|
-
let viewId: number;
|
|
20
|
-
let viewName: string;
|
|
21
|
-
let packageId: number;
|
|
22
|
-
|
|
23
|
-
// If view ID provided directly
|
|
24
|
-
if (viewIdentifier && /^\d+$/.test(viewIdentifier)) {
|
|
25
|
-
viewId = parseInt(viewIdentifier);
|
|
26
|
-
const spinner = ora("Obteniendo vista...").start();
|
|
27
|
-
try {
|
|
28
|
-
const view = await getView(viewId);
|
|
29
|
-
viewName = view.name;
|
|
30
|
-
packageId = view.package_id;
|
|
31
|
-
spinner.succeed(`Vista: ${viewName}`);
|
|
32
|
-
} catch (error: any) {
|
|
33
|
-
spinner.fail(chalk.red(`No se encontró la vista ${viewId}`));
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
// Interactive selection
|
|
38
|
-
const spinner = ora("Cargando packages...").start();
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const packages = await listPackages();
|
|
42
|
-
spinner.stop();
|
|
43
|
-
|
|
44
|
-
if (packages.length === 0) {
|
|
45
|
-
console.log(chalk.yellow(" No tienes packages. Crea uno en Developer Center.\n"));
|
|
46
|
-
process.exit(0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
console.log(chalk.gray(" Tus packages:\n"));
|
|
50
|
-
packages.forEach((pkg, i) => {
|
|
51
|
-
console.log(` ${chalk.cyan(i + 1)}. ${pkg.name}`);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// For now, use first package (can improve with interactive selection later)
|
|
55
|
-
const pkg = packages[0];
|
|
56
|
-
packageId = pkg.pk_id;
|
|
57
|
-
console.log(chalk.gray(`\n Usando package: ${pkg.name}\n`));
|
|
58
|
-
|
|
59
|
-
const viewsSpinner = ora("Cargando vistas...").start();
|
|
60
|
-
const views = await listViews(packageId);
|
|
61
|
-
viewsSpinner.stop();
|
|
62
|
-
|
|
63
|
-
if (views.length === 0) {
|
|
64
|
-
console.log(chalk.yellow(" No hay vistas en este package.\n"));
|
|
65
|
-
process.exit(0);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
console.log(chalk.gray(" Vistas disponibles:\n"));
|
|
69
|
-
views.forEach((view, i) => {
|
|
70
|
-
console.log(` ${chalk.cyan(i + 1)}. ${view.name} ${chalk.gray(`(${view.view_type})`)}`);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// If viewIdentifier matches a name
|
|
74
|
-
let selectedView = viewIdentifier
|
|
75
|
-
? views.find(v => v.name.toLowerCase().includes(viewIdentifier.toLowerCase()))
|
|
76
|
-
: views[0];
|
|
77
|
-
|
|
78
|
-
if (!selectedView) {
|
|
79
|
-
console.log(chalk.yellow(`\n No se encontró vista "${viewIdentifier}"\n`));
|
|
80
|
-
console.log(chalk.gray(" Uso: gufi pull <nombre-vista> o gufi pull <view-id>\n"));
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
viewId = selectedView.pk_id;
|
|
85
|
-
viewName = selectedView.name;
|
|
86
|
-
|
|
87
|
-
console.log(chalk.gray(`\n Descargando: ${viewName}\n`));
|
|
88
|
-
|
|
89
|
-
} catch (error: any) {
|
|
90
|
-
spinner.fail(chalk.red(error.message));
|
|
91
|
-
process.exit(1);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Pull the view
|
|
96
|
-
const pullSpinner = ora("Descargando archivos...").start();
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
const result = await pullView(viewId, viewName, packageId);
|
|
100
|
-
pullSpinner.succeed(chalk.green(`${result.fileCount} archivos descargados`));
|
|
101
|
-
|
|
102
|
-
console.log(chalk.gray(`\n 📁 ${result.dir}\n`));
|
|
103
|
-
console.log(chalk.gray(" Comandos útiles:"));
|
|
104
|
-
console.log(chalk.cyan(" cd " + result.dir));
|
|
105
|
-
console.log(chalk.cyan(" gufi watch") + chalk.gray(" # Auto-sync cambios"));
|
|
106
|
-
console.log(chalk.cyan(" claude") + chalk.gray(" # Abrir Claude Code"));
|
|
107
|
-
console.log();
|
|
108
|
-
|
|
109
|
-
} catch (error: any) {
|
|
110
|
-
pullSpinner.fail(chalk.red(error.message));
|
|
111
|
-
process.exit(1);
|
|
112
|
-
}
|
|
113
|
-
}
|
package/src/commands/push.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gufi push - Upload local changes to Gufi
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import ora from "ora";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import { pushView, getChangedFiles, loadViewMeta } from "../lib/sync.js";
|
|
9
|
-
import { isLoggedIn, getCurrentView } from "../lib/config.js";
|
|
10
|
-
|
|
11
|
-
export async function pushCommand(viewDir?: string): Promise<void> {
|
|
12
|
-
if (!isLoggedIn()) {
|
|
13
|
-
console.log(chalk.red("\n ✗ No estás logueado. Usa: gufi login\n"));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
console.log(chalk.magenta("\n 🟣 Gufi Push\n"));
|
|
18
|
-
|
|
19
|
-
// Determine view directory
|
|
20
|
-
const dir = viewDir || getCurrentView()?.localPath || process.cwd();
|
|
21
|
-
|
|
22
|
-
// Check if it's a valid Gufi view directory
|
|
23
|
-
const meta = loadViewMeta(dir);
|
|
24
|
-
if (!meta) {
|
|
25
|
-
console.log(chalk.red(" ✗ No es un directorio de vista Gufi válido."));
|
|
26
|
-
console.log(chalk.gray(" Usa: gufi pull <vista> primero\n"));
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log(chalk.gray(` Vista: ${meta.viewName}`));
|
|
31
|
-
console.log(chalk.gray(` Directorio: ${dir}\n`));
|
|
32
|
-
|
|
33
|
-
// Check for changes
|
|
34
|
-
const changedFiles = getChangedFiles(dir);
|
|
35
|
-
|
|
36
|
-
if (changedFiles.length === 0) {
|
|
37
|
-
console.log(chalk.green(" ✓ No hay cambios para subir\n"));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(chalk.gray(" Archivos modificados:"));
|
|
42
|
-
changedFiles.forEach((file) => {
|
|
43
|
-
console.log(chalk.yellow(` • ${file}`));
|
|
44
|
-
});
|
|
45
|
-
console.log();
|
|
46
|
-
|
|
47
|
-
// Push changes
|
|
48
|
-
const spinner = ora("Subiendo cambios...").start();
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const result = await pushView(dir);
|
|
52
|
-
spinner.succeed(chalk.green(`${result.pushed} archivo(s) subido(s)`));
|
|
53
|
-
console.log(chalk.gray("\n El preview en Gufi se actualizará automáticamente.\n"));
|
|
54
|
-
} catch (error: any) {
|
|
55
|
-
spinner.fail(chalk.red(error.message));
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function statusCommand(viewDir?: string): Promise<void> {
|
|
61
|
-
const dir = viewDir || getCurrentView()?.localPath || process.cwd();
|
|
62
|
-
|
|
63
|
-
const meta = loadViewMeta(dir);
|
|
64
|
-
if (!meta) {
|
|
65
|
-
console.log(chalk.red("\n ✗ No es un directorio de vista Gufi válido.\n"));
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
console.log(chalk.magenta("\n 🟣 Gufi Status\n"));
|
|
70
|
-
console.log(chalk.gray(` Vista: ${meta.viewName}`));
|
|
71
|
-
console.log(chalk.gray(` View ID: ${meta.viewId}`));
|
|
72
|
-
console.log(chalk.gray(` Último sync: ${meta.lastSync}\n`));
|
|
73
|
-
|
|
74
|
-
const changedFiles = getChangedFiles(dir);
|
|
75
|
-
|
|
76
|
-
if (changedFiles.length === 0) {
|
|
77
|
-
console.log(chalk.green(" ✓ Todo sincronizado\n"));
|
|
78
|
-
} else {
|
|
79
|
-
console.log(chalk.yellow(" Archivos modificados:"));
|
|
80
|
-
changedFiles.forEach((file) => {
|
|
81
|
-
console.log(chalk.yellow(` • ${file}`));
|
|
82
|
-
});
|
|
83
|
-
console.log(chalk.gray("\n Usa: gufi push para subir cambios\n"));
|
|
84
|
-
}
|
|
85
|
-
}
|
package/src/commands/watch.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gufi watch - Auto-sync file changes to Gufi
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import chokidar from "chokidar";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import { pushSingleFile, loadViewMeta, getViewDir } from "../lib/sync.js";
|
|
9
|
-
import { isLoggedIn, getCurrentView } from "../lib/config.js";
|
|
10
|
-
|
|
11
|
-
export async function watchCommand(viewDir?: string): Promise<void> {
|
|
12
|
-
if (!isLoggedIn()) {
|
|
13
|
-
console.log(chalk.red("\n ✗ No estás logueado. Usa: gufi login\n"));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Determine view directory
|
|
18
|
-
const dir = viewDir || getCurrentView()?.localPath || process.cwd();
|
|
19
|
-
|
|
20
|
-
const meta = loadViewMeta(dir);
|
|
21
|
-
if (!meta) {
|
|
22
|
-
console.log(chalk.red("\n ✗ No es un directorio de vista Gufi válido."));
|
|
23
|
-
console.log(chalk.gray(" Usa: gufi pull <vista> primero\n"));
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
console.log(chalk.magenta("\n 🟣 Gufi Watch\n"));
|
|
28
|
-
console.log(chalk.gray(` Vista: ${meta.viewName}`));
|
|
29
|
-
console.log(chalk.gray(` Directorio: ${dir}\n`));
|
|
30
|
-
console.log(chalk.green(" ✓ Observando cambios...\n"));
|
|
31
|
-
console.log(chalk.gray(" Ctrl+C para salir\n"));
|
|
32
|
-
|
|
33
|
-
// Setup file watcher
|
|
34
|
-
const watcher = chokidar.watch(dir, {
|
|
35
|
-
ignored: [
|
|
36
|
-
/(^|[\/\\])\../, // Hidden files
|
|
37
|
-
"**/node_modules/**",
|
|
38
|
-
"**/.gufi-view.json",
|
|
39
|
-
],
|
|
40
|
-
persistent: true,
|
|
41
|
-
ignoreInitial: true,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Debounce map to prevent rapid duplicate syncs
|
|
45
|
-
const debounceMap = new Map<string, NodeJS.Timeout>();
|
|
46
|
-
|
|
47
|
-
const syncFile = async (filePath: string) => {
|
|
48
|
-
const relativePath = path.relative(dir, filePath);
|
|
49
|
-
|
|
50
|
-
// Clear existing debounce
|
|
51
|
-
const existing = debounceMap.get(relativePath);
|
|
52
|
-
if (existing) {
|
|
53
|
-
clearTimeout(existing);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Set new debounce
|
|
57
|
-
debounceMap.set(
|
|
58
|
-
relativePath,
|
|
59
|
-
setTimeout(async () => {
|
|
60
|
-
debounceMap.delete(relativePath);
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
process.stdout.write(chalk.yellow(` ↑ ${relativePath}...`));
|
|
64
|
-
await pushSingleFile(dir, relativePath);
|
|
65
|
-
process.stdout.write(chalk.green(" ✓\n"));
|
|
66
|
-
} catch (error: any) {
|
|
67
|
-
process.stdout.write(chalk.red(` ✗ ${error.message}\n`));
|
|
68
|
-
}
|
|
69
|
-
}, 300)
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
watcher
|
|
74
|
-
.on("change", syncFile)
|
|
75
|
-
.on("add", syncFile)
|
|
76
|
-
.on("error", (error) => {
|
|
77
|
-
console.log(chalk.red(` Error: ${error.message}`));
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Handle graceful shutdown
|
|
81
|
-
process.on("SIGINT", () => {
|
|
82
|
-
console.log(chalk.gray("\n\n Deteniendo watch...\n"));
|
|
83
|
-
watcher.close();
|
|
84
|
-
process.exit(0);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// Keep process alive
|
|
88
|
-
await new Promise(() => {});
|
|
89
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Gufi Dev CLI - Main Entry Point
|
|
4
|
-
*
|
|
5
|
-
* Commands:
|
|
6
|
-
* gufi login Login to Gufi
|
|
7
|
-
* gufi logout Logout from Gufi
|
|
8
|
-
* gufi whoami Show current user
|
|
9
|
-
* gufi pull [view] Download view files
|
|
10
|
-
* gufi push Upload local changes
|
|
11
|
-
* gufi watch Auto-sync file changes
|
|
12
|
-
* gufi status Show sync status
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { Command } from "commander";
|
|
16
|
-
import { loginCommand, logoutCommand, whoamiCommand } from "./commands/login.js";
|
|
17
|
-
import { pullCommand } from "./commands/pull.js";
|
|
18
|
-
import { pushCommand, statusCommand } from "./commands/push.js";
|
|
19
|
-
import { watchCommand } from "./commands/watch.js";
|
|
20
|
-
import { listCommand } from "./commands/list.js";
|
|
21
|
-
|
|
22
|
-
const program = new Command();
|
|
23
|
-
|
|
24
|
-
program
|
|
25
|
-
.name("gufi")
|
|
26
|
-
.description("Gufi Developer CLI - Develop Gufi views locally")
|
|
27
|
-
.version("0.1.0");
|
|
28
|
-
|
|
29
|
-
// Auth commands
|
|
30
|
-
program
|
|
31
|
-
.command("login")
|
|
32
|
-
.description("Login to Gufi")
|
|
33
|
-
.option("--api <url>", "Custom API URL")
|
|
34
|
-
.action(loginCommand);
|
|
35
|
-
|
|
36
|
-
program
|
|
37
|
-
.command("logout")
|
|
38
|
-
.description("Logout from Gufi")
|
|
39
|
-
.action(logoutCommand);
|
|
40
|
-
|
|
41
|
-
program
|
|
42
|
-
.command("whoami")
|
|
43
|
-
.description("Show current logged in user")
|
|
44
|
-
.action(whoamiCommand);
|
|
45
|
-
|
|
46
|
-
// Sync commands
|
|
47
|
-
program
|
|
48
|
-
.command("pull [view]")
|
|
49
|
-
.description("Download view files from Gufi")
|
|
50
|
-
.action(pullCommand);
|
|
51
|
-
|
|
52
|
-
program
|
|
53
|
-
.command("push")
|
|
54
|
-
.description("Upload local changes to Gufi")
|
|
55
|
-
.action(pushCommand);
|
|
56
|
-
|
|
57
|
-
program
|
|
58
|
-
.command("watch")
|
|
59
|
-
.description("Watch for file changes and auto-sync")
|
|
60
|
-
.action(watchCommand);
|
|
61
|
-
|
|
62
|
-
program
|
|
63
|
-
.command("status")
|
|
64
|
-
.description("Show sync status")
|
|
65
|
-
.action(statusCommand);
|
|
66
|
-
|
|
67
|
-
program
|
|
68
|
-
.command("list")
|
|
69
|
-
.alias("ls")
|
|
70
|
-
.description("List your packages and views")
|
|
71
|
-
.action(listCommand);
|
|
72
|
-
|
|
73
|
-
program.parse();
|
package/src/lib/api.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gufi Dev CLI - API Client
|
|
3
|
-
* Communicates with Gufi Marketplace API
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { getToken, getApiUrl } from "./config.js";
|
|
7
|
-
|
|
8
|
-
export interface ViewFile {
|
|
9
|
-
id?: number;
|
|
10
|
-
file_path: string;
|
|
11
|
-
content: string;
|
|
12
|
-
language: string;
|
|
13
|
-
is_entry_point?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface View {
|
|
17
|
-
pk_id: number;
|
|
18
|
-
name: string;
|
|
19
|
-
description?: string;
|
|
20
|
-
view_type: string;
|
|
21
|
-
package_id: number;
|
|
22
|
-
config?: Record<string, any>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface Package {
|
|
26
|
-
pk_id: number;
|
|
27
|
-
name: string;
|
|
28
|
-
description?: string;
|
|
29
|
-
company_id: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class ApiError extends Error {
|
|
33
|
-
constructor(public status: number, message: string) {
|
|
34
|
-
super(message);
|
|
35
|
-
this.name = "ApiError";
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function request<T>(
|
|
40
|
-
endpoint: string,
|
|
41
|
-
options: RequestInit = {}
|
|
42
|
-
): Promise<T> {
|
|
43
|
-
const token = getToken();
|
|
44
|
-
if (!token) {
|
|
45
|
-
throw new Error("No estás logueado. Ejecuta: gufi login");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const url = `${getApiUrl()}${endpoint}`;
|
|
49
|
-
const response = await fetch(url, {
|
|
50
|
-
...options,
|
|
51
|
-
headers: {
|
|
52
|
-
"Content-Type": "application/json",
|
|
53
|
-
Authorization: `Bearer ${token}`,
|
|
54
|
-
...options.headers,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (!response.ok) {
|
|
59
|
-
const text = await response.text();
|
|
60
|
-
throw new ApiError(response.status, `API Error ${response.status}: ${text}`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return response.json();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ============ Auth ============
|
|
67
|
-
|
|
68
|
-
export async function login(email: string, password: string): Promise<{ token: string }> {
|
|
69
|
-
const url = `${getApiUrl()}/api/auth/login`;
|
|
70
|
-
const response = await fetch(url, {
|
|
71
|
-
method: "POST",
|
|
72
|
-
headers: { "Content-Type": "application/json" },
|
|
73
|
-
body: JSON.stringify({ email, password }),
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
throw new ApiError(response.status, "Credenciales inválidas");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const data = await response.json();
|
|
81
|
-
return { token: data.accessToken };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ============ Packages ============
|
|
85
|
-
|
|
86
|
-
export async function listPackages(): Promise<Package[]> {
|
|
87
|
-
return request<Package[]>("/api/marketplace/developer/packages");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ============ Views ============
|
|
91
|
-
|
|
92
|
-
export async function listViews(packageId: number): Promise<View[]> {
|
|
93
|
-
return request<View[]>(`/api/marketplace/packages/${packageId}/views`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export async function getView(viewId: number): Promise<View> {
|
|
97
|
-
return request<View>(`/api/marketplace/views/${viewId}`);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export async function getViewFiles(viewId: number): Promise<ViewFile[]> {
|
|
101
|
-
return request<ViewFile[]>(`/api/marketplace/views/${viewId}/files`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export async function saveViewFiles(viewId: number, files: ViewFile[]): Promise<void> {
|
|
105
|
-
await request(`/api/marketplace/views/${viewId}/files`, {
|
|
106
|
-
method: "PUT",
|
|
107
|
-
body: JSON.stringify({ files }),
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export async function saveViewFile(viewId: number, file: ViewFile): Promise<void> {
|
|
112
|
-
await request(`/api/marketplace/views/${viewId}/files`, {
|
|
113
|
-
method: "PUT",
|
|
114
|
-
body: JSON.stringify({ files: [file] }),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ============ Validation ============
|
|
119
|
-
|
|
120
|
-
export async function validateToken(): Promise<boolean> {
|
|
121
|
-
try {
|
|
122
|
-
await request("/api/auth/me");
|
|
123
|
-
return true;
|
|
124
|
-
} catch {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
}
|
package/src/lib/config.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gufi Dev CLI - Config Management
|
|
3
|
-
* Stores credentials and settings in ~/.gufi/config.json
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import os from "os";
|
|
9
|
-
|
|
10
|
-
export interface GufiConfig {
|
|
11
|
-
apiUrl: string;
|
|
12
|
-
token?: string;
|
|
13
|
-
email?: string;
|
|
14
|
-
currentView?: {
|
|
15
|
-
id: number;
|
|
16
|
-
name: string;
|
|
17
|
-
packageId: number;
|
|
18
|
-
localPath: string;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const CONFIG_DIR = path.join(os.homedir(), ".gufi");
|
|
23
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
24
|
-
|
|
25
|
-
const DEFAULT_CONFIG: GufiConfig = {
|
|
26
|
-
apiUrl: "https://gogufi.com",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export function ensureConfigDir(): void {
|
|
30
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
31
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function loadConfig(): GufiConfig {
|
|
36
|
-
ensureConfigDir();
|
|
37
|
-
if (!fs.existsSync(CONFIG_FILE)) {
|
|
38
|
-
return { ...DEFAULT_CONFIG };
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
const data = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
42
|
-
return { ...DEFAULT_CONFIG, ...JSON.parse(data) };
|
|
43
|
-
} catch {
|
|
44
|
-
return { ...DEFAULT_CONFIG };
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function saveConfig(config: GufiConfig): void {
|
|
49
|
-
ensureConfigDir();
|
|
50
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function getToken(): string | undefined {
|
|
54
|
-
return loadConfig().token;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function setToken(token: string, email: string): void {
|
|
58
|
-
const config = loadConfig();
|
|
59
|
-
config.token = token;
|
|
60
|
-
config.email = email;
|
|
61
|
-
saveConfig(config);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function clearToken(): void {
|
|
65
|
-
const config = loadConfig();
|
|
66
|
-
delete config.token;
|
|
67
|
-
delete config.email;
|
|
68
|
-
saveConfig(config);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function isLoggedIn(): boolean {
|
|
72
|
-
return !!getToken();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function setCurrentView(view: GufiConfig["currentView"]): void {
|
|
76
|
-
const config = loadConfig();
|
|
77
|
-
config.currentView = view;
|
|
78
|
-
saveConfig(config);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function getCurrentView(): GufiConfig["currentView"] | undefined {
|
|
82
|
-
return loadConfig().currentView;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function getApiUrl(): string {
|
|
86
|
-
return loadConfig().apiUrl;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function setApiUrl(url: string): void {
|
|
90
|
-
const config = loadConfig();
|
|
91
|
-
config.apiUrl = url;
|
|
92
|
-
saveConfig(config);
|
|
93
|
-
}
|