@getxflow/cli 0.6.3 → 0.6.5
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/dist/bin.js +7 -0
- package/dist/commands/connections.js +52 -0
- package/dist/commands/deploy.js +4 -0
- package/dist/commands/env.js +6 -1
- package/dist/commands/sources.js +16 -0
- package/dist/help.js +328 -303
- package/dist/version.js +1 -1
- package/package.json +3 -2
- package/skills/xflow/SKILL.md +451 -444
package/dist/bin.js
CHANGED
|
@@ -13,6 +13,7 @@ const zip_1 = require("./zip");
|
|
|
13
13
|
const version_1 = require("./version");
|
|
14
14
|
const auth_1 = require("./commands/auth");
|
|
15
15
|
const projects_1 = require("./commands/projects");
|
|
16
|
+
const connections_1 = require("./commands/connections");
|
|
16
17
|
const db_1 = require("./commands/db");
|
|
17
18
|
const env_1 = require("./commands/env");
|
|
18
19
|
const functions_1 = require("./commands/functions");
|
|
@@ -105,6 +106,12 @@ async function run(args) {
|
|
|
105
106
|
return;
|
|
106
107
|
}
|
|
107
108
|
throw new errors_1.CliError(`Unknown command: env ${second}`, 'Available: list, check, set and rm');
|
|
109
|
+
case 'connections':
|
|
110
|
+
if (second === undefined || second === 'list') {
|
|
111
|
+
await (0, connections_1.connectionsList)();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
throw new errors_1.CliError(`Unknown command: connections ${second}`, 'Available: list');
|
|
108
115
|
case 'schedules':
|
|
109
116
|
if (second === 'set') {
|
|
110
117
|
await (0, schedules_1.schedulesSet)(rest);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectionsList = connectionsList;
|
|
4
|
+
const api_1 = require("../api");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
const session_1 = require("../session");
|
|
7
|
+
const ui_1 = require("../ui");
|
|
8
|
+
// An expiring token is renewed by any build, a revoked one is not renewed by
|
|
9
|
+
// anything until a human reconnects the account. Telling them apart saves a
|
|
10
|
+
// pointless rebuild, so every case gets its own line.
|
|
11
|
+
function state(row) {
|
|
12
|
+
if (!row.alias)
|
|
13
|
+
return 'available, not linked';
|
|
14
|
+
if (row.disabled)
|
|
15
|
+
return 'linked but switched off, the functions get nothing';
|
|
16
|
+
switch (row.health) {
|
|
17
|
+
case 'expiring':
|
|
18
|
+
return `linked, token expires in ${row.days_left} days, any build renews it`;
|
|
19
|
+
case 'expired':
|
|
20
|
+
return 'linked, access has expired, reconnect the account';
|
|
21
|
+
case 'revoked':
|
|
22
|
+
return 'linked, access was revoked by the provider, a rebuild will not help';
|
|
23
|
+
case 'ok':
|
|
24
|
+
return row.days_left === null ? 'linked' : `linked, token valid ${row.days_left} days`;
|
|
25
|
+
default:
|
|
26
|
+
return 'linked';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function connectionsList() {
|
|
30
|
+
const { config } = (0, config_1.requireProject)();
|
|
31
|
+
const client = (0, session_1.connect)(config);
|
|
32
|
+
const data = await (0, api_1.apiJson)(client, `/api/v1/projects/${config.projectId}/connections`);
|
|
33
|
+
if (data.connections.length === 0) {
|
|
34
|
+
(0, ui_1.note)('No connections you can use in this organization');
|
|
35
|
+
(0, ui_1.note)((0, ui_1.dim)(' Somebody connects an account first: platform settings, Connectors'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
(0, ui_1.table)(data.connections.map((row) => [
|
|
39
|
+
row.label,
|
|
40
|
+
row.connector_key ?? '-',
|
|
41
|
+
row.alias ?? '-',
|
|
42
|
+
state(row),
|
|
43
|
+
]));
|
|
44
|
+
const variables = data.connections.flatMap((row) => row.env);
|
|
45
|
+
if (variables.length > 0) {
|
|
46
|
+
(0, ui_1.note)((0, ui_1.dim)(` The functions get: ${variables.join(', ')}`));
|
|
47
|
+
(0, ui_1.note)((0, ui_1.dim)(' A change reaches a function on its next deploy: xflow deploy'));
|
|
48
|
+
}
|
|
49
|
+
if (data.connections.some((row) => !row.alias)) {
|
|
50
|
+
(0, ui_1.note)((0, ui_1.dim)(' To link one: project settings, Connectors. Needs the developer role on the project'));
|
|
51
|
+
}
|
|
52
|
+
}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -120,6 +120,10 @@ async function deploy(args) {
|
|
|
120
120
|
if (started.removed_functions?.length) {
|
|
121
121
|
(0, ui_1.warn)(`Removed from the cloud, gone from the sources: ${started.removed_functions.join(', ')}`);
|
|
122
122
|
}
|
|
123
|
+
if (started.revoked_connections?.length) {
|
|
124
|
+
(0, ui_1.warn)(`Access revoked by the provider: ${started.revoked_connections.join(', ')}`);
|
|
125
|
+
(0, ui_1.note)((0, ui_1.dim)(' Reconnect the account in the platform settings: another build will not fix this'));
|
|
126
|
+
}
|
|
123
127
|
const build = await waitForBuild(client, config.projectId, started);
|
|
124
128
|
if (build.phase === 'failed') {
|
|
125
129
|
if (build.log_tail) {
|
package/dist/commands/env.js
CHANGED
|
@@ -12,6 +12,11 @@ const config_1 = require("../config");
|
|
|
12
12
|
const errors_1 = require("../errors");
|
|
13
13
|
const session_1 = require("../session");
|
|
14
14
|
const ui_1 = require("../ui");
|
|
15
|
+
const SCOPE_LABEL = {
|
|
16
|
+
organization: 'the whole organization',
|
|
17
|
+
project: 'this project only',
|
|
18
|
+
connection: 'from a connected service, read-only',
|
|
19
|
+
};
|
|
15
20
|
const FUNCTIONS_DIR = 'functions';
|
|
16
21
|
/** Matches `process.env.NAME` and `process.env['NAME']`. */
|
|
17
22
|
const ENV_REFERENCE = /process\.env(?:\.([A-Z0-9_]+)|\[['"]([A-Z0-9_]+)['"]\])/g;
|
|
@@ -70,7 +75,7 @@ async function envList() {
|
|
|
70
75
|
(0, ui_1.note)((0, ui_1.dim)(' To store one: xflow env set SMTP_PASSWORD=secret'));
|
|
71
76
|
return;
|
|
72
77
|
}
|
|
73
|
-
(0, ui_1.table)(rows.map((row) => [row.name, row.scope
|
|
78
|
+
(0, ui_1.table)(rows.map((row) => [row.name, SCOPE_LABEL[row.scope] ?? SCOPE_LABEL.organization]));
|
|
74
79
|
(0, ui_1.note)((0, ui_1.dim)(' The platform never returns values: they are visible only inside the function'));
|
|
75
80
|
}
|
|
76
81
|
/** Check that every referenced variable is stored. */
|
package/dist/commands/sources.js
CHANGED
|
@@ -176,6 +176,22 @@ async function status() {
|
|
|
176
176
|
(0, ui_1.out)('');
|
|
177
177
|
(0, ui_1.out)(`Built version: ${card.dev_deploy_id ?? '(no build)'}`);
|
|
178
178
|
(0, ui_1.out)(`Visitors see: ${card.live_deploy_id ?? '(never published)'}`);
|
|
179
|
+
// Two different problems, two different fixes: an expiring token is renewed by
|
|
180
|
+
// any build, a revoked one is not renewed by anything until a human reconnects
|
|
181
|
+
// the account. Telling them apart saves a pointless rebuild.
|
|
182
|
+
const ailing = (card.connections ?? []).filter((c) => c.health !== 'ok');
|
|
183
|
+
if (ailing.length > 0) {
|
|
184
|
+
(0, ui_1.out)('');
|
|
185
|
+
(0, ui_1.out)((0, ui_1.bold)('Connected accounts needing attention:'));
|
|
186
|
+
for (const connection of ailing) {
|
|
187
|
+
const problem = connection.health === 'expiring'
|
|
188
|
+
? `expires in ${connection.days_left} days, any build renews it`
|
|
189
|
+
: connection.health === 'expired'
|
|
190
|
+
? 'access has expired, reconnect the account in the platform settings'
|
|
191
|
+
: 'access was revoked by the provider, reconnect the account in the platform settings';
|
|
192
|
+
(0, ui_1.out)(` ${connection.label} (${connection.alias}): ${problem}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
179
195
|
(0, ui_1.out)('');
|
|
180
196
|
(0, ui_1.out)(card.project_url);
|
|
181
197
|
}
|