@facilio/cli 0.3.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 +21 -0
- package/README.md +120 -0
- package/dist/commands/login.js +75 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +41 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/whoami.js +26 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/core/api.js +158 -0
- package/dist/core/api.js.map +1 -0
- package/dist/core/constants.js +53 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/credentials.js +209 -0
- package/dist/core/credentials.js.map +1 -0
- package/dist/core/identity.js +162 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/logger.js +9 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/prompt.js +29 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/regions.js +45 -0
- package/dist/core/regions.js.map +1 -0
- package/dist/core/secretStore.js +251 -0
- package/dist/core/secretStore.js.map +1 -0
- package/dist/core/wrap.js +17 -0
- package/dist/core/wrap.js.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/products/connections/client.js +125 -0
- package/dist/products/connections/client.js.map +1 -0
- package/dist/products/connections/commands.js +324 -0
- package/dist/products/connections/commands.js.map +1 -0
- package/dist/products/connections/index.js +63 -0
- package/dist/products/connections/index.js.map +1 -0
- package/dist/products/connections/state.js +44 -0
- package/dist/products/connections/state.js.map +1 -0
- package/dist/products/types.js +2 -0
- package/dist/products/types.js.map +1 -0
- package/dist/products/vibe/app.js +97 -0
- package/dist/products/vibe/app.js.map +1 -0
- package/dist/products/vibe/config.js +57 -0
- package/dist/products/vibe/config.js.map +1 -0
- package/dist/products/vibe/db.js +155 -0
- package/dist/products/vibe/db.js.map +1 -0
- package/dist/products/vibe/deploy.js +92 -0
- package/dist/products/vibe/deploy.js.map +1 -0
- package/dist/products/vibe/function.js +240 -0
- package/dist/products/vibe/function.js.map +1 -0
- package/dist/products/vibe/index.js +112 -0
- package/dist/products/vibe/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { logger } from '../../core/logger.js';
|
|
4
|
+
import { loadConfig, resolveAppLinkName } from './config.js';
|
|
5
|
+
import { loadCredentials } from '../../core/credentials.js';
|
|
6
|
+
import { apiFromCredentials } from '../../core/api.js';
|
|
7
|
+
import { prompt } from '../../core/prompt.js';
|
|
8
|
+
/**
|
|
9
|
+
* `facilio vibe db create` — provision the DATABASE addon for the current app.
|
|
10
|
+
*
|
|
11
|
+
* Resolves the app the same way `facilio vibe deploy` does (vibe.json `app`, or
|
|
12
|
+
* `--app`), then calls the CLI addon endpoint. The server reuses the same
|
|
13
|
+
* provisioning chain as the platform UI, so this is idempotent: if the app
|
|
14
|
+
* already has a database, it returns the existing schema/role/user rather than
|
|
15
|
+
* creating anything new.
|
|
16
|
+
*/
|
|
17
|
+
export async function dbCreateCommand(opts) {
|
|
18
|
+
const creds = await loadCredentials();
|
|
19
|
+
if (!creds)
|
|
20
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
21
|
+
const config = await loadConfig();
|
|
22
|
+
const linkName = opts.app ?? resolveAppLinkName(config);
|
|
23
|
+
if (!linkName) {
|
|
24
|
+
throw new Error('No app target. Run `facilio vibe app create <name>` (writes to vibe.json) or pass `--app <linkName>`.');
|
|
25
|
+
}
|
|
26
|
+
const api = await apiFromCredentials(creds);
|
|
27
|
+
logger.info(`Creating database for "${linkName}"...`);
|
|
28
|
+
const res = await api.postJson(`/api/cli/apps/${encodeURIComponent(linkName)}/addons/database`, {});
|
|
29
|
+
const cfg = res.config ?? {};
|
|
30
|
+
logger.success('Database ready.');
|
|
31
|
+
if (cfg.schema)
|
|
32
|
+
logger.step(`Schema: ${cfg.schema}`);
|
|
33
|
+
if (cfg.role?.name)
|
|
34
|
+
logger.step(`Role: ${cfg.role.name}`);
|
|
35
|
+
if (cfg.user?.username)
|
|
36
|
+
logger.step(`User: ${cfg.user.username}`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* `facilio vibe db import` — create a table in the app's database from a CSV file.
|
|
40
|
+
*
|
|
41
|
+
* Columns are inferred from the CSV header/data server-side (ai-studio
|
|
42
|
+
* `importCsv`). Requires the app's database to exist first (`facilio vibe db create`).
|
|
43
|
+
*/
|
|
44
|
+
export async function dbImportCommand(opts) {
|
|
45
|
+
const creds = await loadCredentials();
|
|
46
|
+
if (!creds)
|
|
47
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
48
|
+
const config = await loadConfig();
|
|
49
|
+
const linkName = opts.app ?? resolveAppLinkName(config);
|
|
50
|
+
if (!linkName) {
|
|
51
|
+
throw new Error('No app target. Run `facilio vibe app create <name>` (writes to vibe.json) or pass `--app <linkName>`.');
|
|
52
|
+
}
|
|
53
|
+
const filePath = opts.file ?? (await prompt('CSV file path'));
|
|
54
|
+
if (!filePath)
|
|
55
|
+
throw new Error('A CSV file path is required.');
|
|
56
|
+
const resolvedPath = path.resolve(process.cwd(), filePath);
|
|
57
|
+
let csv;
|
|
58
|
+
try {
|
|
59
|
+
csv = await fs.readFile(resolvedPath);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw new Error(`CSV file not found: ${resolvedPath}`);
|
|
63
|
+
}
|
|
64
|
+
if (csv.length === 0)
|
|
65
|
+
throw new Error('CSV file is empty.');
|
|
66
|
+
const table = opts.table ?? (await prompt('Table name', { default: defaultTableName(resolvedPath) }));
|
|
67
|
+
const api = await apiFromCredentials(creds);
|
|
68
|
+
logger.info(`Importing ${path.basename(resolvedPath)} into "${table}"...`);
|
|
69
|
+
const res = await api.uploadBinary(`/api/cli/apps/${encodeURIComponent(linkName)}/tables?table=${encodeURIComponent(table)}`, csv, 'text/csv');
|
|
70
|
+
logger.success(`Imported ${res.rowCount} row${res.rowCount === 1 ? '' : 's'} into ${res.schema}.${res.table}`);
|
|
71
|
+
const colCount = Array.isArray(res.columns) ? res.columns.length : undefined;
|
|
72
|
+
if (colCount != null)
|
|
73
|
+
logger.step(`Columns: ${colCount}`);
|
|
74
|
+
for (const w of res.warnings ?? [])
|
|
75
|
+
logger.step(`Warning: ${w}`);
|
|
76
|
+
}
|
|
77
|
+
/** Derive a valid default table name from the CSV file name. */
|
|
78
|
+
function defaultTableName(filePath) {
|
|
79
|
+
const stem = path.basename(filePath).replace(/\.[^.]*$/, '').toLowerCase();
|
|
80
|
+
let t = stem.replace(/[^a-z0-9_]/g, '_');
|
|
81
|
+
if (!/^[a-z_]/.test(t))
|
|
82
|
+
t = `t_${t}`;
|
|
83
|
+
return t.slice(0, 63) || 'imported_table';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* `facilio vibe db tables` — list the tables in the app's database (its schema).
|
|
87
|
+
* Requires the app's database to exist first (`facilio vibe db create`).
|
|
88
|
+
*/
|
|
89
|
+
export async function dbTablesCommand(opts) {
|
|
90
|
+
const creds = await loadCredentials();
|
|
91
|
+
if (!creds)
|
|
92
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
93
|
+
const config = await loadConfig();
|
|
94
|
+
const linkName = opts.app ?? resolveAppLinkName(config);
|
|
95
|
+
if (!linkName) {
|
|
96
|
+
throw new Error('No app target. Run `facilio vibe app create <name>` (writes to vibe.json) or pass `--app <linkName>`.');
|
|
97
|
+
}
|
|
98
|
+
const api = await apiFromCredentials(creds);
|
|
99
|
+
const res = await api.getJson(`/api/cli/apps/${encodeURIComponent(linkName)}/tables`);
|
|
100
|
+
const tables = res.tables ?? [];
|
|
101
|
+
if (tables.length === 0) {
|
|
102
|
+
logger.info(`No tables in ${res.schema} yet. Create one with \`facilio vibe db import\`.`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const rows = tables.map((t) => ({
|
|
106
|
+
name: t.name,
|
|
107
|
+
type: t.type ?? '—',
|
|
108
|
+
rows: t.rowCount == null ? '—' : String(t.rowCount),
|
|
109
|
+
}));
|
|
110
|
+
const cols = ['name', 'type', 'rows'];
|
|
111
|
+
const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)));
|
|
112
|
+
const fmt = (vals) => vals.map((v, i) => v.padEnd(widths[i])).join(' ');
|
|
113
|
+
console.log(fmt(cols.map((c) => String(c).toUpperCase())));
|
|
114
|
+
console.log(fmt(widths.map((w) => '-'.repeat(w))));
|
|
115
|
+
for (const r of rows)
|
|
116
|
+
console.log(fmt(cols.map((c) => String(r[c]))));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* `facilio vibe db describe <table>` — show a table's column structure (name, type,
|
|
120
|
+
* nullable) and total row count. Requires the app's database to exist.
|
|
121
|
+
*/
|
|
122
|
+
export async function dbDescribeCommand(table, opts) {
|
|
123
|
+
const creds = await loadCredentials();
|
|
124
|
+
if (!creds)
|
|
125
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
126
|
+
if (!table)
|
|
127
|
+
throw new Error('A table name is required: `facilio vibe db describe <table>`.');
|
|
128
|
+
const config = await loadConfig();
|
|
129
|
+
const linkName = opts.app ?? resolveAppLinkName(config);
|
|
130
|
+
if (!linkName) {
|
|
131
|
+
throw new Error('No app target. Run `facilio vibe app create <name>` (writes to vibe.json) or pass `--app <linkName>`.');
|
|
132
|
+
}
|
|
133
|
+
const api = await apiFromCredentials(creds);
|
|
134
|
+
const res = await api.getJson(`/api/cli/apps/${encodeURIComponent(linkName)}/tables/${encodeURIComponent(table)}`);
|
|
135
|
+
const rowCount = res.rowCount == null ? '—' : String(res.rowCount);
|
|
136
|
+
logger.info(`${res.schema}.${res.table} (${rowCount} row${rowCount === '1' ? '' : 's'})`);
|
|
137
|
+
const columns = res.columns ?? [];
|
|
138
|
+
if (columns.length === 0) {
|
|
139
|
+
logger.step('No columns.');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const rows = columns.map((c) => ({
|
|
143
|
+
column: c.name,
|
|
144
|
+
type: c.type ?? '—',
|
|
145
|
+
nullable: c.nullable ? 'yes' : 'no',
|
|
146
|
+
}));
|
|
147
|
+
const cols = ['column', 'type', 'nullable'];
|
|
148
|
+
const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)));
|
|
149
|
+
const fmt = (vals) => vals.map((v, i) => v.padEnd(widths[i])).join(' ');
|
|
150
|
+
console.log(fmt(cols.map((c) => String(c).toUpperCase())));
|
|
151
|
+
console.log(fmt(widths.map((w) => '-'.repeat(w))));
|
|
152
|
+
for (const r of rows)
|
|
153
|
+
console.log(fmt(cols.map((c) => String(r[c]))));
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/products/vibe/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import archiver from 'archiver';
|
|
4
|
+
import { logger } from '../../core/logger.js';
|
|
5
|
+
import { loadConfig, resolveAppLinkName } from './config.js';
|
|
6
|
+
import { loadCredentials } from '../../core/credentials.js';
|
|
7
|
+
import { apiFromCredentials, ApiError } from '../../core/api.js';
|
|
8
|
+
const POLL_INTERVAL_MS = 2000;
|
|
9
|
+
const POLL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
10
|
+
export async function deployCommand(opts) {
|
|
11
|
+
const creds = await loadCredentials();
|
|
12
|
+
if (!creds)
|
|
13
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
14
|
+
const config = await loadConfig();
|
|
15
|
+
const linkName = opts.app ?? resolveAppLinkName(config);
|
|
16
|
+
if (!linkName) {
|
|
17
|
+
throw new Error('No app target. Run `facilio vibe app create <name>` (writes to vibe.json) or pass `--app <linkName>`.');
|
|
18
|
+
}
|
|
19
|
+
const publishDir = path.resolve(process.cwd(), config.build.publish);
|
|
20
|
+
try {
|
|
21
|
+
const stat = await fs.stat(publishDir);
|
|
22
|
+
if (!stat.isDirectory())
|
|
23
|
+
throw new Error('not a directory');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error(`Publish directory not found: ${publishDir}. Build your app first, then set build.publish in vibe.json to that folder.`);
|
|
27
|
+
}
|
|
28
|
+
const api = await apiFromCredentials(creds);
|
|
29
|
+
logger.info(`Zipping ${publishDir}...`);
|
|
30
|
+
const zipBuffer = await zipDirectory(publishDir);
|
|
31
|
+
logger.step(`Bundle size: ${(zipBuffer.length / 1024).toFixed(1)} KB`);
|
|
32
|
+
logger.info(`Starting deployment for app "${linkName}"...`);
|
|
33
|
+
let deployment;
|
|
34
|
+
try {
|
|
35
|
+
deployment = await api.postJson(`/api/cli/apps/${encodeURIComponent(linkName)}/deployments`, { production: !!opts.prod });
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err instanceof ApiError && err.statusCode === 404) {
|
|
39
|
+
throw new Error(`App "${linkName}" doesn't exist. Create it: \`facilio vibe app create ${linkName}\``);
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
logger.step(`Deployment #${deployment.versionNumber} (id=${deployment.deploymentId})`);
|
|
44
|
+
await api.uploadBinary(`/api/cli/deployments/${deployment.deploymentId}/upload`, zipBuffer, 'application/zip');
|
|
45
|
+
logger.info(`Publishing...`);
|
|
46
|
+
const published = await api.postJson(`/api/cli/deployments/${deployment.deploymentId}/publish`, {});
|
|
47
|
+
const final = await pollUntilDone(api, deployment.deploymentId, published);
|
|
48
|
+
if (final.status === 'DEPLOYED') {
|
|
49
|
+
logger.success(`Deployed v${final.versionNumber}`);
|
|
50
|
+
if (final.url)
|
|
51
|
+
logger.step(`Live: ${final.url}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error(`Deployment ${final.status}: ${final.message ?? 'unknown error'}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function pollUntilDone(api, deploymentId, initial) {
|
|
58
|
+
if (initial.status === 'DEPLOYED' || initial.status === 'FAILED')
|
|
59
|
+
return initial;
|
|
60
|
+
const start = Date.now();
|
|
61
|
+
while (Date.now() - start < POLL_TIMEOUT_MS) {
|
|
62
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
63
|
+
try {
|
|
64
|
+
const status = await api.getJson(`/api/cli/deployments/${deploymentId}`);
|
|
65
|
+
if (status.status === 'DEPLOYED' || status.status === 'FAILED')
|
|
66
|
+
return status;
|
|
67
|
+
logger.step(`Status: ${status.status}`);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err instanceof ApiError && err.statusCode === 404)
|
|
71
|
+
continue;
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
throw new Error('Deployment polling timed out.');
|
|
76
|
+
}
|
|
77
|
+
function zipDirectory(dir) {
|
|
78
|
+
return new Promise((resolve, reject) => {
|
|
79
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
80
|
+
const chunks = [];
|
|
81
|
+
archive.on('data', (c) => chunks.push(c));
|
|
82
|
+
archive.on('warning', (err) => {
|
|
83
|
+
if (err.code !== 'ENOENT')
|
|
84
|
+
reject(err);
|
|
85
|
+
});
|
|
86
|
+
archive.on('error', reject);
|
|
87
|
+
archive.on('end', () => resolve(Buffer.concat(chunks)));
|
|
88
|
+
archive.directory(dir, false);
|
|
89
|
+
archive.finalize().catch(reject);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/products/vibe/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { logger } from '../../core/logger.js';
|
|
4
|
+
import { loadConfig, resolveAppLinkName } from './config.js';
|
|
5
|
+
import { loadCredentials } from '../../core/credentials.js';
|
|
6
|
+
import { apiFromCredentials, ApiError } from '../../core/api.js';
|
|
7
|
+
import { prompt } from '../../core/prompt.js';
|
|
8
|
+
async function api() {
|
|
9
|
+
const creds = await loadCredentials();
|
|
10
|
+
if (!creds)
|
|
11
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
12
|
+
return apiFromCredentials(creds);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* `facilio vibe function instructions` — print the authoritative guide for writing a
|
|
16
|
+
* function. Fetched by vibe-server from ai-studio (the same source the platform
|
|
17
|
+
* uses), so it never drifts from a hand-copied template. Org-level; no app needed.
|
|
18
|
+
*/
|
|
19
|
+
export async function functionInstructionsCommand() {
|
|
20
|
+
const client = await api();
|
|
21
|
+
const res = await client.getJson('/api/cli/functions/instructions');
|
|
22
|
+
if (!res.instructions) {
|
|
23
|
+
logger.info('No instructions returned.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(res.instructions);
|
|
27
|
+
}
|
|
28
|
+
/** Resolve the target app link name from `--app` or vibe.json, else error. */
|
|
29
|
+
async function resolveLink(app) {
|
|
30
|
+
const linkName = app ?? resolveAppLinkName(await loadConfig());
|
|
31
|
+
if (!linkName) {
|
|
32
|
+
throw new Error('No app target. Run inside a vibe app directory (vibe.json) or pass `--app <linkName>`.');
|
|
33
|
+
}
|
|
34
|
+
return linkName;
|
|
35
|
+
}
|
|
36
|
+
function fnBase(linkName) {
|
|
37
|
+
return `/api/cli/apps/${encodeURIComponent(linkName)}/functions`;
|
|
38
|
+
}
|
|
39
|
+
/** GET the function, returning null on a 404 (so callers can branch on existence). */
|
|
40
|
+
async function fetchFunction(client, linkName, name) {
|
|
41
|
+
try {
|
|
42
|
+
return await client.getJson(`${fnBase(linkName)}/${encodeURIComponent(name)}`);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err instanceof ApiError && err.statusCode === 404)
|
|
46
|
+
return null;
|
|
47
|
+
throw err;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Read the --code / --package files (prompting for code if omitted). */
|
|
51
|
+
async function readSources(opts) {
|
|
52
|
+
const codePath = opts.code ?? (await prompt('Path to function code (.js/.ts)'));
|
|
53
|
+
if (!codePath)
|
|
54
|
+
throw new Error('A code file is required (--code <path>).');
|
|
55
|
+
const code = await readTextFile(codePath, 'code');
|
|
56
|
+
let packageJson;
|
|
57
|
+
if (opts.package)
|
|
58
|
+
packageJson = await readTextFile(opts.package, 'package.json');
|
|
59
|
+
return { code, packageJson };
|
|
60
|
+
}
|
|
61
|
+
async function readTextFile(filePath, label) {
|
|
62
|
+
const resolved = path.resolve(process.cwd(), filePath);
|
|
63
|
+
let contents;
|
|
64
|
+
try {
|
|
65
|
+
contents = await fs.readFile(resolved, 'utf8');
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
throw new Error(`${label} file not found: ${resolved}`);
|
|
69
|
+
}
|
|
70
|
+
if (contents.trim().length === 0)
|
|
71
|
+
throw new Error(`${label} file is empty: ${resolved}`);
|
|
72
|
+
return contents;
|
|
73
|
+
}
|
|
74
|
+
/** Shared upsert — PUT is idempotent server-side; create/update only differ in the pre-check. */
|
|
75
|
+
async function putFunction(client, linkName, name, sources, description) {
|
|
76
|
+
return client.putJson(`${fnBase(linkName)}/${encodeURIComponent(name)}`, {
|
|
77
|
+
code: sources.code,
|
|
78
|
+
packageJson: sources.packageJson,
|
|
79
|
+
description,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** `facilio vibe function create <name>` — upload a new function. Fails if it already exists. */
|
|
83
|
+
export async function functionCreateCommand(name, opts) {
|
|
84
|
+
requireName(name);
|
|
85
|
+
const linkName = await resolveLink(opts.app);
|
|
86
|
+
const client = await api();
|
|
87
|
+
const existing = await fetchFunction(client, linkName, name);
|
|
88
|
+
if (existing) {
|
|
89
|
+
throw new Error(`Function "${name}" already exists in "${linkName}". Use \`facilio vibe function update ${name}\` instead.`);
|
|
90
|
+
}
|
|
91
|
+
const sources = await readSources(opts);
|
|
92
|
+
logger.info(`Creating function "${name}" in "${linkName}"...`);
|
|
93
|
+
await putFunction(client, linkName, name, sources, opts.description);
|
|
94
|
+
logger.success(`Created "${name}". Build it with \`facilio vibe function build ${name}\`.`);
|
|
95
|
+
}
|
|
96
|
+
/** `facilio vibe function update <name>` — replace an existing function's source. Fails if missing. */
|
|
97
|
+
export async function functionUpdateCommand(name, opts) {
|
|
98
|
+
requireName(name);
|
|
99
|
+
const linkName = await resolveLink(opts.app);
|
|
100
|
+
const client = await api();
|
|
101
|
+
const existing = await fetchFunction(client, linkName, name);
|
|
102
|
+
if (!existing) {
|
|
103
|
+
throw new Error(`Function "${name}" not found in "${linkName}". Use \`facilio vibe function create ${name}\` first.`);
|
|
104
|
+
}
|
|
105
|
+
const sources = await readSources(opts);
|
|
106
|
+
// Preserve the existing description unless a new one is passed.
|
|
107
|
+
const description = opts.description ?? existing.description;
|
|
108
|
+
logger.info(`Updating function "${name}" in "${linkName}"...`);
|
|
109
|
+
await putFunction(client, linkName, name, sources, description);
|
|
110
|
+
logger.success(`Updated "${name}". Re-build it with \`facilio vibe function build ${name}\`.`);
|
|
111
|
+
}
|
|
112
|
+
/** `facilio vibe function list` — list the app's functions. */
|
|
113
|
+
export async function functionListCommand(opts) {
|
|
114
|
+
const linkName = await resolveLink(opts.app);
|
|
115
|
+
const client = await api();
|
|
116
|
+
const res = await client.getJson(fnBase(linkName));
|
|
117
|
+
const functions = res.functions ?? [];
|
|
118
|
+
if (functions.length === 0) {
|
|
119
|
+
logger.info(`No functions in "${linkName}" yet. Create one with \`facilio vibe function create <name> --code <file>\`.`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const rows = functions.map((f) => ({
|
|
123
|
+
name: f.name,
|
|
124
|
+
built: f.built ? 'yes' : 'no',
|
|
125
|
+
description: f.description ?? '—',
|
|
126
|
+
}));
|
|
127
|
+
const cols = ['name', 'built', 'description'];
|
|
128
|
+
const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)));
|
|
129
|
+
const fmt = (vals) => vals.map((v, i) => v.padEnd(widths[i])).join(' ');
|
|
130
|
+
console.log(fmt(cols.map((c) => String(c).toUpperCase())));
|
|
131
|
+
console.log(fmt(widths.map((w) => '-'.repeat(w))));
|
|
132
|
+
for (const r of rows)
|
|
133
|
+
console.log(fmt(cols.map((c) => String(r[c]))));
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* `facilio vibe function get <name>` — show a function's build state and (by default) its
|
|
137
|
+
* source. Pass `--code-only` to print just the code (e.g. to redirect to a file).
|
|
138
|
+
*/
|
|
139
|
+
export async function functionGetCommand(name, opts) {
|
|
140
|
+
requireName(name);
|
|
141
|
+
const linkName = await resolveLink(opts.app);
|
|
142
|
+
const client = await api();
|
|
143
|
+
const info = await fetchFunction(client, linkName, name);
|
|
144
|
+
if (!info)
|
|
145
|
+
throw new Error(`Function "${name}" not found in "${linkName}".`);
|
|
146
|
+
if (opts.codeOnly) {
|
|
147
|
+
if (info.code)
|
|
148
|
+
process.stdout.write(info.code.endsWith('\n') ? info.code : info.code + '\n');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
logger.info(`${info.name} (${info.built ? 'built' : 'not built'})`);
|
|
152
|
+
if (info.description)
|
|
153
|
+
logger.step(info.description);
|
|
154
|
+
if (info.code) {
|
|
155
|
+
logger.step('--- code ---');
|
|
156
|
+
console.log(info.code);
|
|
157
|
+
}
|
|
158
|
+
if (info.packageJson) {
|
|
159
|
+
logger.step('--- package.json ---');
|
|
160
|
+
console.log(info.packageJson);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** `facilio vibe function delete <name>` — remove a function and all its artifacts. */
|
|
164
|
+
export async function functionDeleteCommand(name, opts) {
|
|
165
|
+
requireName(name);
|
|
166
|
+
const linkName = await resolveLink(opts.app);
|
|
167
|
+
const client = await api();
|
|
168
|
+
try {
|
|
169
|
+
const res = await client.deleteJson(`${fnBase(linkName)}/${encodeURIComponent(name)}`);
|
|
170
|
+
logger.success(`Deleted "${res.name}" from "${linkName}".`);
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
if (err instanceof ApiError && err.statusCode === 404) {
|
|
174
|
+
throw new Error(`Function "${name}" not found in "${linkName}".`);
|
|
175
|
+
}
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/** `facilio vibe function build <name>` — compile the uploaded source to WASM. */
|
|
180
|
+
export async function functionBuildCommand(name, opts) {
|
|
181
|
+
requireName(name);
|
|
182
|
+
const linkName = await resolveLink(opts.app);
|
|
183
|
+
const client = await api();
|
|
184
|
+
logger.info(`Building "${name}" in "${linkName}" (this can take a while)...`);
|
|
185
|
+
const res = await client.postJson(`${fnBase(linkName)}/${encodeURIComponent(name)}/build`, {});
|
|
186
|
+
if (res.ok === false) {
|
|
187
|
+
throw new Error(`Build failed: ${res.error ?? 'unknown error'}`);
|
|
188
|
+
}
|
|
189
|
+
logger.success(`Built "${res.name}".`);
|
|
190
|
+
if (res.builtAt)
|
|
191
|
+
logger.step(`Built at: ${res.builtAt}`);
|
|
192
|
+
if (res.wasmSizeBytes != null)
|
|
193
|
+
logger.step(`WASM size: ${res.wasmSizeBytes} bytes`);
|
|
194
|
+
const endpoints = res.endpoints ?? [];
|
|
195
|
+
if (endpoints.length > 0) {
|
|
196
|
+
logger.step(`Handlers: ${endpoints.map((e) => e.name).join(', ')}`);
|
|
197
|
+
logger.step(`Run one with \`facilio vibe function run ${res.name} <handler>\`.`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* `facilio vibe function run <name> <handler>` — execute one handler. `--args` is a JSON
|
|
202
|
+
* object of handler arguments. Secrets (connections/agents tokens, and the app's
|
|
203
|
+
* DB schema/user for SQL) are injected by the backend, never passed here.
|
|
204
|
+
*/
|
|
205
|
+
export async function functionRunCommand(name, handler, opts) {
|
|
206
|
+
requireName(name);
|
|
207
|
+
if (!handler)
|
|
208
|
+
throw new Error('A handler name is required: `facilio vibe function run <name> <handler>`.');
|
|
209
|
+
const args = parseArgs(opts.args);
|
|
210
|
+
const linkName = await resolveLink(opts.app);
|
|
211
|
+
const client = await api();
|
|
212
|
+
logger.info(`Running "${name}" › ${handler} in "${linkName}"...`);
|
|
213
|
+
const res = await client.postJson(`${fnBase(linkName)}/${encodeURIComponent(name)}/handlers/${encodeURIComponent(handler)}/run`, { args });
|
|
214
|
+
if (res.ok === false) {
|
|
215
|
+
throw new Error(`Function errored: ${res.error ?? 'unknown error'}`);
|
|
216
|
+
}
|
|
217
|
+
// The handler's return value — print as JSON so structured output round-trips.
|
|
218
|
+
console.log(typeof res.output === 'string' ? res.output : JSON.stringify(res.output, null, 2));
|
|
219
|
+
}
|
|
220
|
+
function requireName(name) {
|
|
221
|
+
if (!name || !name.trim())
|
|
222
|
+
throw new Error('A function name is required.');
|
|
223
|
+
}
|
|
224
|
+
/** Parse the --args JSON object, rejecting non-objects with a clear message. */
|
|
225
|
+
function parseArgs(raw) {
|
|
226
|
+
if (!raw)
|
|
227
|
+
return {};
|
|
228
|
+
let parsed;
|
|
229
|
+
try {
|
|
230
|
+
parsed = JSON.parse(raw);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
throw new Error('--args must be valid JSON.');
|
|
234
|
+
}
|
|
235
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
236
|
+
throw new Error('--args must be a JSON object (e.g. \'{"name":"world"}\').');
|
|
237
|
+
}
|
|
238
|
+
return parsed;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=function.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../../src/products/vibe/function.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { wrap } from '../../core/wrap.js';
|
|
2
|
+
import { deployCommand } from './deploy.js';
|
|
3
|
+
import { appCreateCommand, appListCommand } from './app.js';
|
|
4
|
+
import { dbCreateCommand, dbImportCommand, dbTablesCommand, dbDescribeCommand } from './db.js';
|
|
5
|
+
import { functionCreateCommand, functionUpdateCommand, functionListCommand, functionGetCommand, functionDeleteCommand, functionBuildCommand, functionRunCommand, functionInstructionsCommand, } from './function.js';
|
|
6
|
+
/** `facilio vibe …` — the former standalone vibe CLI, unchanged behavior. */
|
|
7
|
+
export const vibeProduct = {
|
|
8
|
+
name: 'vibe',
|
|
9
|
+
description: 'Build and deploy Vibe apps (deploy / app / db / function)',
|
|
10
|
+
register(parent, _ctx) {
|
|
11
|
+
const vibe = parent.command('vibe').description(this.description);
|
|
12
|
+
vibe
|
|
13
|
+
.command('deploy')
|
|
14
|
+
.description('Deploy the current project to its app (zips build.publish dir and uploads)')
|
|
15
|
+
.option('--prod', 'Mark this deployment as production')
|
|
16
|
+
.option('--app <linkName>', 'Override the app target from vibe.json')
|
|
17
|
+
.action(wrap(deployCommand));
|
|
18
|
+
const app = vibe
|
|
19
|
+
.command('app')
|
|
20
|
+
.description('Manage Vibe apps (create / list)');
|
|
21
|
+
app
|
|
22
|
+
.command('create')
|
|
23
|
+
.description('Create a new app (prompts for name, description, logo)')
|
|
24
|
+
.option('--name <name>', 'App name — linkName/subdomain is derived from this server-side')
|
|
25
|
+
.option('--description <text>', 'Optional description')
|
|
26
|
+
.option('--logo <url>', 'Optional public URL to a logo image')
|
|
27
|
+
.action(wrap(appCreateCommand));
|
|
28
|
+
app
|
|
29
|
+
.command('list')
|
|
30
|
+
.alias('ls')
|
|
31
|
+
.description('List apps in your org')
|
|
32
|
+
.action(wrap(appListCommand));
|
|
33
|
+
const db = vibe
|
|
34
|
+
.command('db')
|
|
35
|
+
.description('Manage the app database addon');
|
|
36
|
+
db
|
|
37
|
+
.command('create')
|
|
38
|
+
.description('Provision a database (schema + role + user) for the current app. Idempotent — returns the existing one if already created.')
|
|
39
|
+
.option('--app <linkName>', 'Override the app target from vibe.json')
|
|
40
|
+
.action(wrap(dbCreateCommand));
|
|
41
|
+
db
|
|
42
|
+
.command('import')
|
|
43
|
+
.description('Create a table in the app database by importing a CSV file (columns inferred). Requires `facilio vibe db create` first.')
|
|
44
|
+
.option('--file <path>', 'Path to the CSV file')
|
|
45
|
+
.option('--table <name>', 'Target table name (defaults to the file name)')
|
|
46
|
+
.option('--app <linkName>', 'Override the app target from vibe.json')
|
|
47
|
+
.action(wrap(dbImportCommand));
|
|
48
|
+
db
|
|
49
|
+
.command('tables')
|
|
50
|
+
.alias('ls')
|
|
51
|
+
.description('List the tables in the app database')
|
|
52
|
+
.option('--app <linkName>', 'Override the app target from vibe.json')
|
|
53
|
+
.action(wrap(dbTablesCommand));
|
|
54
|
+
db
|
|
55
|
+
.command('describe <table>')
|
|
56
|
+
.alias('desc')
|
|
57
|
+
.description("Show a table's columns (name, type, nullable) and row count")
|
|
58
|
+
.option('--app <linkName>', 'Override the app target from vibe.json')
|
|
59
|
+
.action(wrap(dbDescribeCommand));
|
|
60
|
+
const fn = vibe
|
|
61
|
+
.command('function')
|
|
62
|
+
.alias('fn')
|
|
63
|
+
.description("Manage an app's functions: create / update / list / get / delete / build / run");
|
|
64
|
+
const appOpt = (c) => c.option('--app <linkName>', "Target app (defaults to vibe.json's app)");
|
|
65
|
+
appOpt(fn
|
|
66
|
+
.command('create <name>')
|
|
67
|
+
.description('Upload a new function from a code file. Fails if it already exists in the app.')
|
|
68
|
+
.option('--code <path>', 'Path to the function source file')
|
|
69
|
+
.option('--package <path>', 'Optional path to a package.json for the function')
|
|
70
|
+
.option('--description <text>', 'Optional description'))
|
|
71
|
+
.action(wrap(functionCreateCommand));
|
|
72
|
+
appOpt(fn
|
|
73
|
+
.command('update <name>')
|
|
74
|
+
.description("Replace an existing function's source. Fails if it does not exist.")
|
|
75
|
+
.option('--code <path>', 'Path to the function source file')
|
|
76
|
+
.option('--package <path>', 'Optional path to a package.json for the function')
|
|
77
|
+
.option('--description <text>', 'Update the description'))
|
|
78
|
+
.action(wrap(functionUpdateCommand));
|
|
79
|
+
appOpt(fn
|
|
80
|
+
.command('list')
|
|
81
|
+
.alias('ls')
|
|
82
|
+
.description("List the app's functions"))
|
|
83
|
+
.action(wrap(functionListCommand));
|
|
84
|
+
appOpt(fn
|
|
85
|
+
.command('get <name>')
|
|
86
|
+
.alias('show')
|
|
87
|
+
.description("Show a function's build state and source")
|
|
88
|
+
.option('--code-only', 'Print only the code (useful for redirecting to a file)'))
|
|
89
|
+
.action(wrap(functionGetCommand));
|
|
90
|
+
appOpt(fn
|
|
91
|
+
.command('delete <name>')
|
|
92
|
+
.alias('rm')
|
|
93
|
+
.description('Delete a function and all its artifacts'))
|
|
94
|
+
.action(wrap(functionDeleteCommand));
|
|
95
|
+
appOpt(fn
|
|
96
|
+
.command('build <name>')
|
|
97
|
+
.description('Compile the uploaded function to WASM'))
|
|
98
|
+
.action(wrap(functionBuildCommand));
|
|
99
|
+
appOpt(fn
|
|
100
|
+
.command('run <name> <handler>')
|
|
101
|
+
.alias('exec')
|
|
102
|
+
.description('Execute a handler of a built function')
|
|
103
|
+
.option('--args <json>', 'Handler arguments as a JSON object, e.g. \'{"name":"world"}\''))
|
|
104
|
+
.action(wrap(functionRunCommand));
|
|
105
|
+
fn
|
|
106
|
+
.command('instructions')
|
|
107
|
+
.alias('guide')
|
|
108
|
+
.description('Print the authoritative guide for writing a function (fetched from ai-studio)')
|
|
109
|
+
.action(wrap(functionInstructionsCommand));
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=index.js.map
|