@getxflow/cli 1.0.5 → 1.0.7
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/commands/auth.js +2 -0
- package/dist/commands/db.js +7 -1
- package/dist/version.js +1 -1
- package/package.json +24 -24
- package/skills/xflow/SKILL.md +16 -11
package/dist/commands/auth.js
CHANGED
|
@@ -141,6 +141,8 @@ async function whoami() {
|
|
|
141
141
|
const pkg = me.billing.package_title ? `, ${me.billing.package_title}` : '';
|
|
142
142
|
(0, ui_1.out)('');
|
|
143
143
|
(0, ui_1.out)(`Plan: ${me.billing.plan_title}${pkg}${SUBSCRIPTION_STATE[me.billing.status] ?? ''}`);
|
|
144
|
+
if (me.billing.functions_stopped)
|
|
145
|
+
(0, ui_1.warn)(me.billing.functions_stopped);
|
|
144
146
|
}
|
|
145
147
|
if (me.quotas) {
|
|
146
148
|
(0, ui_1.out)('');
|
package/dist/commands/db.js
CHANGED
|
@@ -148,7 +148,13 @@ function moveLine(move) {
|
|
|
148
148
|
return move.finished_at ? `${move.note} (${(0, ui_1.formatAge)(move.finished_at)})` : move.note;
|
|
149
149
|
}
|
|
150
150
|
function printDatabases(databases, total, truncated) {
|
|
151
|
-
(0, ui_1.table)(databases.map((database) => [
|
|
151
|
+
(0, ui_1.table)(databases.map((database) => [
|
|
152
|
+
database.name,
|
|
153
|
+
database.id,
|
|
154
|
+
database.schema ?? '-',
|
|
155
|
+
serverLabel(database.server),
|
|
156
|
+
typeof database.bytes === 'number' ? (0, ui_1.formatBytes)(database.bytes) : '',
|
|
157
|
+
]));
|
|
152
158
|
if (truncated)
|
|
153
159
|
(0, ui_1.note)((0, ui_1.dim)(` Shown ${databases.length} of ${total}`));
|
|
154
160
|
for (const database of databases) {
|
package/dist/version.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEFAULT_API_URL = exports.CLI_VERSION = void 0;
|
|
4
4
|
/** Keep in sync with cli/package.json. */
|
|
5
|
-
exports.CLI_VERSION = '1.0.
|
|
5
|
+
exports.CLI_VERSION = '1.0.7';
|
|
6
6
|
/** Overridden by XFLOW_API_URL or the `api` field in xflow.json. */
|
|
7
7
|
exports.DEFAULT_API_URL = 'https://app.getxflow.com';
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@getxflow/cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "CLI for the XFlow platform: projects with apps, functions and a database; source sync, deployment and publishing",
|
|
5
|
-
"license": "UNLICENSED",
|
|
6
|
-
"engines": {
|
|
7
|
-
"node": ">=20"
|
|
8
|
-
},
|
|
9
|
-
"bin": {
|
|
10
|
-
"xflow": "dist/bin.js"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"dist",
|
|
14
|
-
"skills"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
18
|
-
"build": "npm run clean && tsc -p tsconfig.json",
|
|
19
|
-
"prepublishOnly": "npm run build"
|
|
20
|
-
},
|
|
21
|
-
"publishConfig": {
|
|
22
|
-
"access": "public"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@getxflow/cli",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"description": "CLI for the XFlow platform: projects with apps, functions and a database; source sync, deployment and publishing",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"xflow": "dist/bin.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"skills"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
18
|
+
"build": "npm run clean && tsc -p tsconfig.json",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/skills/xflow/SKILL.md
CHANGED
|
@@ -23,7 +23,7 @@ contains the fix.
|
|
|
23
23
|
|
|
24
24
|
## Keeping these instructions current
|
|
25
25
|
|
|
26
|
-
These instructions ship with xflow CLI 1.0.
|
|
26
|
+
These instructions ship with xflow CLI 1.0.7, so the copy you are reading can be older than
|
|
27
27
|
the CLI answering your commands.
|
|
28
28
|
|
|
29
29
|
When the CLI says this file does not match it, run `xflow skills --refresh` and then **read
|
|
@@ -59,7 +59,8 @@ the error points away from the cause. The sections below carry the details.
|
|
|
59
59
|
7. When `xflow db migrate` answers `db_write_locked`, or an INSERT or CREATE TABLE in a
|
|
60
60
|
function fails with `permission denied` (42501), the database is over its plan size and
|
|
61
61
|
Postgres itself refuses. Reads, updates and deletes keep working, so the fix is a migration
|
|
62
|
-
that deletes data, never a rewrite of the SQL. Write comes back within the hour.
|
|
62
|
+
that deletes data, never a rewrite of the SQL. Write comes back within the hour. The limit
|
|
63
|
+
is shared by the organization: `xflow db list` shows the size of each project database.
|
|
63
64
|
8. Heavy media does not travel with the sources. Photos, video and PDFs go up with
|
|
64
65
|
`xflow storage push`, not into the repository: the archive is capped at 10 MB.
|
|
65
66
|
|
|
@@ -312,22 +313,26 @@ At the closed levels do none of this: the platform already knows the person.
|
|
|
312
313
|
with `crypto.timingSafeEqual`. Never log a password, never return it, never keep it in the
|
|
313
314
|
browser.
|
|
314
315
|
- Session: after sign-in the function makes a random token (`crypto.randomBytes(32)`), stores
|
|
315
|
-
its SHA-256 and an expiry in a table and returns
|
|
316
|
-
`
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
316
|
+
its SHA-256 and an expiry in a table and returns the token in the response body. The app keeps
|
|
317
|
+
it in `localStorage` and sends it on every call in the `X-Session` header. Not a cookie: Cloud
|
|
318
|
+
Functions drop `Cookie` and `Set-Cookie` both ways. `localStorage` belongs to one address, a
|
|
319
|
+
neighbouring `*.xflowpage.ru` site does not read it.
|
|
320
|
+
- Any script on the page reads that token, so: an expiry of hours that each call extends,
|
|
321
|
+
sign-out and a password change delete the session rows, no user text rendered as HTML
|
|
322
|
+
(`dangerouslySetInnerHTML`), no scripts loaded from outside the build.
|
|
323
|
+
- Never put the token into an address (`?session=`, a link): it stays in history and logs. A file
|
|
324
|
+
the function makes for this person is fetched with the header and opened as a `blob:` URL.
|
|
320
325
|
- Not the `Authorization` header: `/_fn` replaces it with the platform's own. Nor headers named
|
|
321
326
|
`X-Xflow-*`, `X-Project-Pass`, `X-Server-Key`, `X-Function-Key`: the platform strips them.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
327
|
+
- Every function that serves a signed-in visitor reads `X-Session` from `event.headers` (match
|
|
328
|
+
the name in any case), finds the session and filters rows by that user in SQL. A hidden button
|
|
329
|
+
is not access control.
|
|
325
330
|
- Count failed sign-ins per email and per `event.xflow.ip` in a table and slow them down.
|
|
326
331
|
- Never in the frontend: keys, secrets, the list of users, hashes, a role check that is the only
|
|
327
332
|
guard.
|
|
328
333
|
- The platform sends no email for your app: confirmation and reset letters need a mail provider
|
|
329
334
|
whose key goes into `xflow env set`.
|
|
330
|
-
- `xflow dev`
|
|
335
|
+
- `xflow dev` does not carry `X-Session` and calls functions as you (a member).
|
|
331
336
|
Try the sign-in on the app address.
|
|
332
337
|
|
|
333
338
|
## Page or app
|