@xano/cli 1.0.4 → 1.0.6-beta.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/README.md +139 -4
- package/dist/base-command.d.ts +27 -0
- package/dist/base-command.js +124 -1
- package/dist/commands/auth/index.d.ts +45 -1
- package/dist/commands/auth/index.js +197 -29
- package/dist/commands/ephemeral/create/index.d.ts +18 -0
- package/dist/commands/ephemeral/create/index.js +103 -0
- package/dist/commands/ephemeral/delete/index.d.ts +18 -0
- package/dist/commands/ephemeral/delete/index.js +99 -0
- package/dist/commands/ephemeral/edit/index.d.ts +18 -0
- package/dist/commands/ephemeral/edit/index.js +109 -0
- package/dist/commands/ephemeral/get/index.d.ts +21 -0
- package/dist/commands/ephemeral/get/index.js +125 -0
- package/dist/commands/ephemeral/impersonate/index.d.ts +19 -0
- package/dist/commands/ephemeral/impersonate/index.js +112 -0
- package/dist/commands/ephemeral/list/index.d.ts +19 -0
- package/dist/commands/ephemeral/list/index.js +122 -0
- package/dist/commands/ephemeral/pull/index.d.ts +23 -0
- package/dist/commands/ephemeral/pull/index.js +248 -0
- package/dist/commands/{knowledge → ephemeral}/push/index.d.ts +8 -5
- package/dist/commands/ephemeral/push/index.js +143 -0
- package/dist/commands/function/run/index.d.ts +40 -0
- package/dist/commands/function/run/index.js +244 -0
- package/dist/commands/knowledge/{pull → get}/index.d.ts +6 -2
- package/dist/commands/knowledge/get/index.js +126 -0
- package/dist/commands/knowledge/list/index.d.ts +18 -0
- package/dist/commands/knowledge/list/index.js +135 -0
- package/dist/commands/sandbox/pull/index.js +12 -2
- package/dist/commands/sandbox/push/index.d.ts +1 -1
- package/dist/commands/sandbox/push/index.js +19 -14
- package/dist/commands/sandbox/reset/index.js +12 -0
- package/dist/commands/static_host/build/create/index.d.ts +9 -1
- package/dist/commands/static_host/build/create/index.js +54 -4
- package/dist/commands/static_host/build/delete/index.d.ts +19 -0
- package/dist/commands/static_host/build/delete/index.js +114 -0
- package/dist/commands/static_host/build/get/index.d.ts +1 -1
- package/dist/commands/static_host/build/get/index.js +16 -10
- package/dist/commands/static_host/build/pull/index.d.ts +52 -0
- package/dist/commands/static_host/build/pull/index.js +300 -0
- package/dist/commands/static_host/build/push/index.d.ts +23 -0
- package/dist/commands/static_host/build/push/index.js +228 -0
- package/dist/commands/static_host/create/index.d.ts +17 -0
- package/dist/commands/static_host/create/index.js +86 -0
- package/dist/commands/static_host/deploy/index.d.ts +18 -0
- package/dist/commands/static_host/deploy/index.js +105 -0
- package/dist/commands/static_host/edit/index.d.ts +23 -0
- package/dist/commands/static_host/edit/index.js +151 -0
- package/dist/commands/static_host/get/index.d.ts +18 -0
- package/dist/commands/static_host/get/index.js +94 -0
- package/dist/commands/static_host/migrate/index.d.ts +44 -0
- package/dist/commands/static_host/migrate/index.js +205 -0
- package/dist/commands/tenant/snapshot/create/index.d.ts +17 -0
- package/dist/commands/tenant/snapshot/create/index.js +78 -0
- package/dist/commands/tenant/snapshot/delete/index.d.ts +19 -0
- package/dist/commands/tenant/snapshot/delete/index.js +102 -0
- package/dist/commands/tenant/snapshot/list/index.d.ts +16 -0
- package/dist/commands/tenant/snapshot/list/index.js +96 -0
- package/dist/commands/tenant/snapshot/swap/index.d.ts +19 -0
- package/dist/commands/tenant/snapshot/swap/index.js +103 -0
- package/dist/commands/tenant/unit_test/run/index.d.ts +1 -0
- package/dist/commands/tenant/unit_test/run/index.js +7 -0
- package/dist/commands/tenant/unit_test/run_all/index.js +7 -3
- package/dist/commands/unit_test/run/index.d.ts +1 -0
- package/dist/commands/unit_test/run/index.js +8 -0
- package/dist/commands/unit_test/run_all/index.js +7 -3
- package/dist/commands/workspace/pull/index.js +13 -2
- package/dist/commands/workspace/push/index.d.ts +1 -1
- package/dist/commands/workspace/push/index.js +15 -5
- package/dist/utils/function-input.d.ts +77 -0
- package/dist/utils/function-input.js +148 -0
- package/dist/utils/knowledge-sync.d.ts +84 -79
- package/dist/utils/knowledge-sync.js +376 -323
- package/dist/utils/multidoc-push.d.ts +30 -18
- package/dist/utils/multidoc-push.js +284 -148
- package/dist/utils/reference-checker.js +2 -2
- package/dist/utils/static-host-files.d.ts +21 -0
- package/dist/utils/static-host-files.js +41 -0
- package/oclif.manifest.json +5046 -2691
- package/package.json +10 -1
- package/dist/commands/knowledge/pull/index.js +0 -86
- package/dist/commands/knowledge/push/index.js +0 -126
package/README.md
CHANGED
|
@@ -47,6 +47,13 @@ xano auth
|
|
|
47
47
|
xano auth --origin https://custom.xano.com
|
|
48
48
|
xano auth --insecure # Skip TLS verification (self-signed certs)
|
|
49
49
|
xano auth --no-browser # Headless login (no local callback server)
|
|
50
|
+
|
|
51
|
+
# Pre-select instance/workspace/branch and profile name (skips the pickers)
|
|
52
|
+
xano auth -i my-instance -w 5 -b dev -p staging
|
|
53
|
+
xano auth --instance my-instance --workspace "My Workspace" --branch dev --profile staging
|
|
54
|
+
|
|
55
|
+
# Pass "" to take a picker's default: skip workspace, use live branch, default profile name
|
|
56
|
+
xano auth -i my-instance -w 5 -b "" -p ""
|
|
50
57
|
```
|
|
51
58
|
|
|
52
59
|
The default flow starts a temporary callback server on `127.0.0.1` and waits
|
|
@@ -55,12 +62,20 @@ containers, or locked-down networks where the browser can't reach the CLI's
|
|
|
55
62
|
loopback address, use `--no-browser`: the CLI prints a login URL, you open it
|
|
56
63
|
in any browser, and paste back the code it displays. No local server required.
|
|
57
64
|
|
|
65
|
+
Each picker can be pre-answered with a flag: `-i/--instance` (instance name, or numeric instance ID),
|
|
66
|
+
`-w/--workspace` (workspace ID or name), `-b/--branch` (branch label), and
|
|
67
|
+
`-p/--profile` (profile name to save). An empty value (`""`) takes the
|
|
68
|
+
picker's default answer: `-w ""` skips workspace selection, `-b ""` skips and
|
|
69
|
+
uses the live branch, and `-p ""` uses the default profile name. With all four
|
|
70
|
+
set alongside `--no-browser`, the only input is pasting the code from the
|
|
71
|
+
browser — useful for scripted or remote setups.
|
|
72
|
+
|
|
58
73
|
When stdin is piped (not a TTY), `--no-browser` reads the code directly from
|
|
59
74
|
stdin instead of prompting, so scripts and AI agents can complete the flow
|
|
60
75
|
without an interactive terminal:
|
|
61
76
|
|
|
62
77
|
```bash
|
|
63
|
-
echo "$CODE" | xano auth --no-browser
|
|
78
|
+
echo "$CODE" | xano auth --no-browser -i my-instance -w 5 -b dev -p staging
|
|
64
79
|
```
|
|
65
80
|
|
|
66
81
|
If you can't run `xano auth` at all, you can always create a profile manually
|
|
@@ -240,6 +255,58 @@ xano function edit <function_id> -f new.xs # Update from file
|
|
|
240
255
|
xano function edit <function_id> -f new.xs --edit # Open in $EDITOR before updating
|
|
241
256
|
cat function.xs | xano function edit <function_id> --stdin # Update from stdin
|
|
242
257
|
xano function edit <function_id> --no-publish # Edit without publishing
|
|
258
|
+
|
|
259
|
+
# Run (execute) a function by name
|
|
260
|
+
xano function run <name> # Prompts for declared inputs (on a TTY)
|
|
261
|
+
xano function run <name> --data email=jo@x.com --data age:=30 --data active:=true
|
|
262
|
+
xano function run <name> --json @payload.json --data env=staging # base payload + override
|
|
263
|
+
echo '{"email":"jo@x.com"}' | xano function run <name> --stdin -o json | jq .result
|
|
264
|
+
xano function run <name> --branch dev --logs # run on a branch, show execution logs
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Input flexibility for `function run` (assembled into one JSON `input` object):
|
|
268
|
+
|
|
269
|
+
| Form | Meaning |
|
|
270
|
+
| --- | --- |
|
|
271
|
+
| `--data key=value` | string field |
|
|
272
|
+
| `--data key:=<json>` | raw JSON field (`age:=30`, `active:=true`, `tags:='["a","b"]'`) |
|
|
273
|
+
| `--data key@file` | field value read from a file |
|
|
274
|
+
| `--json '<inline>'` / `--json @file.json` / `--json -` | a base JSON object (stdin with `-`) |
|
|
275
|
+
| `--stdin` | read the JSON object from stdin (same as `--json -`) |
|
|
276
|
+
|
|
277
|
+
Merge order is JSON base first, then `--data` overrides. Missing required inputs are
|
|
278
|
+
prompted for on an interactive terminal; in a non-TTY (CI) context the command fails
|
|
279
|
+
listing them. Output defaults to the raw `result` (`-o json`); the exit code is non-zero
|
|
280
|
+
when the function returns an error status.
|
|
281
|
+
|
|
282
|
+
> **Permissions:** running a function requires **Function** (read) plus the **run/debug**
|
|
283
|
+
> action on your workspace role. If your access token's role lacks run/debug, the call is
|
|
284
|
+
> denied with an access error — grant run/debug to the role (or use a token whose role has
|
|
285
|
+
> it). `function list`/`get`/`create`/`edit` only need the Function permission.
|
|
286
|
+
|
|
287
|
+
### Knowledge
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# List all enabled knowledge as markdown (always-on items show full content, on-demand show name + description)
|
|
291
|
+
xano knowledge list -w 40
|
|
292
|
+
|
|
293
|
+
# List as JSON
|
|
294
|
+
xano knowledge list -w 40 --output json
|
|
295
|
+
|
|
296
|
+
# Filter by knowledge type (skill, doc, agents.md)
|
|
297
|
+
xano knowledge list -w 40 --type skill
|
|
298
|
+
|
|
299
|
+
# Include disabled items
|
|
300
|
+
xano knowledge list --no-enabled-only
|
|
301
|
+
|
|
302
|
+
# Get a specific knowledge item's content by name
|
|
303
|
+
xano knowledge get "deploy-runbook" -w 40
|
|
304
|
+
|
|
305
|
+
# Get as JSON (includes all metadata)
|
|
306
|
+
xano knowledge get "deploy-runbook" -w 40 --output json
|
|
307
|
+
|
|
308
|
+
# Get a reference file attached to a knowledge item
|
|
309
|
+
xano knowledge get "deploy-runbook" -w 40 --file checklist.md
|
|
243
310
|
```
|
|
244
311
|
|
|
245
312
|
### Releases
|
|
@@ -311,6 +378,7 @@ xano unit_test list --branch dev --obj-type function
|
|
|
311
378
|
|
|
312
379
|
# Run a single unit test
|
|
313
380
|
xano unit_test run <unit_test_id>
|
|
381
|
+
xano unit_test run <unit_test_id> --branch dev # run the test from a specific branch
|
|
314
382
|
|
|
315
383
|
# Run all unit tests
|
|
316
384
|
xano unit_test run_all
|
|
@@ -496,6 +564,38 @@ xano tenant cluster license set <cluster_id>
|
|
|
496
564
|
xano tenant cluster license set <cluster_id> --file ./kubeconfig.yaml
|
|
497
565
|
```
|
|
498
566
|
|
|
567
|
+
### Ephemeral Tenants
|
|
568
|
+
|
|
569
|
+
Manage ephemeral tenants — short-lived, auto-expiring tenants scoped to a workspace (default TTL 1h, max 72h). Unlike a sandbox, an ephemeral tenant requires a workspace.
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
# List ephemeral tenants in the current workspace
|
|
573
|
+
xano ephemeral list
|
|
574
|
+
xano ephemeral list -w 5
|
|
575
|
+
|
|
576
|
+
# List ephemeral tenants across every workspace you can access
|
|
577
|
+
xano ephemeral list --global
|
|
578
|
+
|
|
579
|
+
# Create an ephemeral tenant (workspace required)
|
|
580
|
+
xano ephemeral create "PR preview"
|
|
581
|
+
xano ephemeral create "Demo" --expires-hours 24 -w 5
|
|
582
|
+
xano ephemeral create "Load test" -d "48h soak" --expires-hours 48
|
|
583
|
+
|
|
584
|
+
# Get / edit / delete
|
|
585
|
+
xano ephemeral get <tenant_name>
|
|
586
|
+
xano ephemeral edit <tenant_name> --display "New Name" -d "New description"
|
|
587
|
+
xano ephemeral delete <tenant_name> --force
|
|
588
|
+
|
|
589
|
+
# Pull to / push from local files (multidoc)
|
|
590
|
+
xano ephemeral pull -t <tenant_name> -d ./my-ephemeral
|
|
591
|
+
xano ephemeral push -t <tenant_name> -d ./my-ephemeral --dry-run # preview first
|
|
592
|
+
xano ephemeral push -t <tenant_name> -d ./my-ephemeral
|
|
593
|
+
|
|
594
|
+
# Open in the browser (or print the URL)
|
|
595
|
+
xano ephemeral impersonate <tenant_name>
|
|
596
|
+
xano ephemeral impersonate <tenant_name> --url-only
|
|
597
|
+
```
|
|
598
|
+
|
|
499
599
|
### Sandbox
|
|
500
600
|
|
|
501
601
|
Manage your sandbox tenant. Each user has a single sandbox tenant that is auto-provisioned on first use.
|
|
@@ -541,14 +641,49 @@ xano sandbox reset --force
|
|
|
541
641
|
# List static hosts
|
|
542
642
|
xano static_host list
|
|
543
643
|
|
|
544
|
-
# Create a
|
|
545
|
-
xano static_host
|
|
644
|
+
# Create / get / edit a static host
|
|
645
|
+
xano static_host create marketing --description "Marketing site"
|
|
646
|
+
xano static_host get marketing
|
|
647
|
+
xano static_host edit marketing --name marketing-v2 --description "Updated"
|
|
546
648
|
|
|
547
649
|
# List builds
|
|
548
650
|
xano static_host build list default
|
|
549
651
|
|
|
550
652
|
# Get build details
|
|
551
|
-
xano static_host build get default 52
|
|
653
|
+
xano static_host build get default --build_id 52
|
|
654
|
+
|
|
655
|
+
# Pull a build to disk. Defaults to the original uploaded source
|
|
656
|
+
# (including package.json). Use --source built for the compiled/served output.
|
|
657
|
+
xano static_host build pull default --build_id 52 # By build ID (original source)
|
|
658
|
+
xano static_host build pull default --build_id 52 --source built # Compiled output
|
|
659
|
+
xano static_host build pull default --latest # Latest build
|
|
660
|
+
xano static_host build pull default --env dev # Build currently deployed to dev
|
|
661
|
+
xano static_host build pull default --env prod -d ./prod-release
|
|
662
|
+
|
|
663
|
+
# Push a build (name optional — auto-generated from the timestamp if omitted).
|
|
664
|
+
# Accepts a directory (-d) or a zip file (-f). Defaults to the current directory.
|
|
665
|
+
# When pushing a directory, files matched by its .gitignore are skipped by default
|
|
666
|
+
# (the .git/ folder is always excluded); use --no-gitignore to push everything.
|
|
667
|
+
# For package.json builds, the CLI waits for the build to finish (--no-wait to skip).
|
|
668
|
+
xano static_host build push default -d ./dist -n "v1.0.0"
|
|
669
|
+
xano static_host build push default # current dir, auto-name
|
|
670
|
+
xano static_host build push default -f ./build.zip -n "v1.0.0" # from zip file
|
|
671
|
+
xano static_host build push default -n "release" --description "Production build"
|
|
672
|
+
xano static_host build push default -d ./static --no-gitignore # push gitignored files too
|
|
673
|
+
|
|
674
|
+
# Delete a build (prompts for confirmation; --force to skip)
|
|
675
|
+
xano static_host build delete default --build_id 52
|
|
676
|
+
xano static_host build delete default --build_id 52 --force
|
|
677
|
+
|
|
678
|
+
# Deploy a build to an environment
|
|
679
|
+
xano static_host deploy default --build_id 52 --env dev
|
|
680
|
+
xano static_host deploy default --build_id 52 --env prod
|
|
681
|
+
|
|
682
|
+
# Migrate a host to instance-managed (v2) hosting
|
|
683
|
+
xano static_host migrate newsite # one host (both envs)
|
|
684
|
+
xano static_host migrate newsite --env dev # one env
|
|
685
|
+
xano static_host migrate --all # every v1 host in the workspace
|
|
686
|
+
xano static_host migrate --all --dry-run # preview without changing anything
|
|
552
687
|
```
|
|
553
688
|
|
|
554
689
|
## Global Options
|
package/dist/base-command.d.ts
CHANGED
|
@@ -103,4 +103,31 @@ export default abstract class BaseCommand extends Command {
|
|
|
103
103
|
* Use this for all Metadata API calls to support the --verbose flag.
|
|
104
104
|
*/
|
|
105
105
|
protected verboseFetch(url: string, options: RequestInit, verbose: boolean, authToken?: string): Promise<Response>;
|
|
106
|
+
/**
|
|
107
|
+
* Poll a static-host build until it reaches a terminal status (ok | error),
|
|
108
|
+
* showing a live, ticking spinner with the current stage and elapsed time —
|
|
109
|
+
* mirroring the UI's build progress for async (package.json) builds, which
|
|
110
|
+
* keep running after the upload returns.
|
|
111
|
+
*
|
|
112
|
+
* On a TTY it renders an animated spinner via ux.action; when quiet (JSON
|
|
113
|
+
* output) or non-interactive it falls back to plain one-line status updates.
|
|
114
|
+
*
|
|
115
|
+
* Returns the final status. Resolves to the last-seen status on timeout.
|
|
116
|
+
*/
|
|
117
|
+
protected logStaticHostUrls(opts: {
|
|
118
|
+
profile: ProfileConfig;
|
|
119
|
+
staticHost: string;
|
|
120
|
+
verbose: boolean;
|
|
121
|
+
workspaceId: string;
|
|
122
|
+
}): Promise<void>;
|
|
123
|
+
protected waitForBuild(opts: {
|
|
124
|
+
buildId: number | string;
|
|
125
|
+
intervalMs?: number;
|
|
126
|
+
profile: ProfileConfig;
|
|
127
|
+
quiet?: boolean;
|
|
128
|
+
staticHost: string;
|
|
129
|
+
timeoutMs?: number;
|
|
130
|
+
verbose: boolean;
|
|
131
|
+
workspaceId: string;
|
|
132
|
+
}): Promise<string>;
|
|
106
133
|
}
|
package/dist/base-command.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command, Flags } from '@oclif/core';
|
|
1
|
+
import { Command, Flags, ux } from '@oclif/core';
|
|
2
2
|
import * as yaml from 'js-yaml';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
4
|
import * as os from 'node:os';
|
|
@@ -358,4 +358,127 @@ export default class BaseCommand extends Command {
|
|
|
358
358
|
}
|
|
359
359
|
return response;
|
|
360
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Poll a static-host build until it reaches a terminal status (ok | error),
|
|
363
|
+
* showing a live, ticking spinner with the current stage and elapsed time —
|
|
364
|
+
* mirroring the UI's build progress for async (package.json) builds, which
|
|
365
|
+
* keep running after the upload returns.
|
|
366
|
+
*
|
|
367
|
+
* On a TTY it renders an animated spinner via ux.action; when quiet (JSON
|
|
368
|
+
* output) or non-interactive it falls back to plain one-line status updates.
|
|
369
|
+
*
|
|
370
|
+
* Returns the final status. Resolves to the last-seen status on timeout.
|
|
371
|
+
*/
|
|
372
|
+
async logStaticHostUrls(opts) {
|
|
373
|
+
const { profile, staticHost, verbose, workspaceId } = opts;
|
|
374
|
+
const url = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/static_host/${staticHost}`;
|
|
375
|
+
try {
|
|
376
|
+
const response = await this.verboseFetch(url, {
|
|
377
|
+
headers: { accept: 'application/json', Authorization: `Bearer ${profile.access_token}` },
|
|
378
|
+
method: 'GET',
|
|
379
|
+
}, verbose, profile.access_token);
|
|
380
|
+
if (!response.ok)
|
|
381
|
+
return;
|
|
382
|
+
const host = (await response.json());
|
|
383
|
+
if (host.dev?.default_url)
|
|
384
|
+
this.log(`Dev URL: ${host.dev.default_url}`);
|
|
385
|
+
if (host.dev?.custom_url)
|
|
386
|
+
this.log(`Dev Custom URL: ${host.dev.custom_url}`);
|
|
387
|
+
if (host.prod?.default_url)
|
|
388
|
+
this.log(`Prod URL: ${host.prod.default_url}`);
|
|
389
|
+
if (host.prod?.custom_url)
|
|
390
|
+
this.log(`Prod Custom URL: ${host.prod.custom_url}`);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Non-fatal — the build succeeded, we just can't show the URL.
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
async waitForBuild(opts) {
|
|
397
|
+
const { buildId, profile, quiet, staticHost, verbose, workspaceId } = opts;
|
|
398
|
+
const intervalMs = opts.intervalMs ?? 2000;
|
|
399
|
+
const timeoutMs = opts.timeoutMs ?? 600_000; // 10 min
|
|
400
|
+
const terminal = new Set(['error', 'ok']);
|
|
401
|
+
const url = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/static_host/${staticHost}/build/${buildId}`;
|
|
402
|
+
// Spinner only on an interactive TTY and when not emitting JSON. Verbose mode
|
|
403
|
+
// also disables it (the spinner would interleave with request/response logs).
|
|
404
|
+
const animate = Boolean(process.stdout.isTTY) && !quiet && !verbose;
|
|
405
|
+
const start = Date.now();
|
|
406
|
+
const elapsed = () => Math.round((Date.now() - start) / 1000);
|
|
407
|
+
let stage = 'pending';
|
|
408
|
+
let ticker;
|
|
409
|
+
// Reflect the current stage: live spinner status on a TTY, else a plain line.
|
|
410
|
+
const render = () => {
|
|
411
|
+
if (animate) {
|
|
412
|
+
ux.action.status = `${stageLabel(stage)} (${elapsed()}s)`;
|
|
413
|
+
}
|
|
414
|
+
else if (!quiet && !terminal.has(stage)) {
|
|
415
|
+
this.log(`Build status: ${stage}`);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
// Stop the spinner/ticker and emit a final line.
|
|
419
|
+
const conclude = (message) => {
|
|
420
|
+
if (ticker)
|
|
421
|
+
clearInterval(ticker);
|
|
422
|
+
if (animate) {
|
|
423
|
+
ux.action.stop(message);
|
|
424
|
+
}
|
|
425
|
+
else if (!quiet) {
|
|
426
|
+
this.log(message);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
if (animate) {
|
|
430
|
+
ux.action.start('Building', stageLabel(stage));
|
|
431
|
+
// Re-render every 120ms so the elapsed counter ticks even between polls.
|
|
432
|
+
ticker = setInterval(render, 120);
|
|
433
|
+
}
|
|
434
|
+
else if (!quiet) {
|
|
435
|
+
this.log(`Build status: ${stage}`);
|
|
436
|
+
}
|
|
437
|
+
/* eslint-disable no-await-in-loop */
|
|
438
|
+
while (Date.now() - start < timeoutMs) {
|
|
439
|
+
const response = await this.verboseFetch(url, {
|
|
440
|
+
headers: { accept: 'application/json', Authorization: `Bearer ${profile.access_token}` },
|
|
441
|
+
method: 'GET',
|
|
442
|
+
}, verbose, profile.access_token);
|
|
443
|
+
if (response.ok) {
|
|
444
|
+
const build = (await response.json());
|
|
445
|
+
const status = build.status ?? 'pending';
|
|
446
|
+
if (status !== stage) {
|
|
447
|
+
stage = status;
|
|
448
|
+
render();
|
|
449
|
+
}
|
|
450
|
+
if (terminal.has(status)) {
|
|
451
|
+
const took = `${elapsed()}s`;
|
|
452
|
+
conclude(status === 'ok' ? `done in ${took}` : `failed after ${took}`);
|
|
453
|
+
return status;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
await new Promise((resolve) => {
|
|
457
|
+
setTimeout(resolve, intervalMs);
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
/* eslint-enable no-await-in-loop */
|
|
461
|
+
conclude(`stopped waiting after ${Math.round(timeoutMs / 1000)}s (last status: ${stage || 'unknown'})`);
|
|
462
|
+
return stage;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/** Human-friendly label for a build status stage. */
|
|
466
|
+
function stageLabel(status) {
|
|
467
|
+
switch (status) {
|
|
468
|
+
case 'building': {
|
|
469
|
+
return 'Installing & building (npm)';
|
|
470
|
+
}
|
|
471
|
+
case 'ok': {
|
|
472
|
+
return 'Finishing';
|
|
473
|
+
}
|
|
474
|
+
case 'pending': {
|
|
475
|
+
return 'Queued';
|
|
476
|
+
}
|
|
477
|
+
case 'publishing': {
|
|
478
|
+
return 'Publishing files';
|
|
479
|
+
}
|
|
480
|
+
default: {
|
|
481
|
+
return status;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
361
484
|
}
|
|
@@ -1,14 +1,53 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
+
export interface Instance {
|
|
3
|
+
display: string;
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
origin: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AuthResult {
|
|
9
|
+
branch: null | string;
|
|
10
|
+
credentialsPath: string;
|
|
11
|
+
instance: {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
origin: string;
|
|
15
|
+
};
|
|
16
|
+
profile: string;
|
|
17
|
+
user: {
|
|
18
|
+
email: string;
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
workspace: null | {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Match a user-supplied --instance value against the instance list:
|
|
29
|
+
* numeric values match by ID, URL/hostname values match by the instance
|
|
30
|
+
* origin's hostname, anything else matches by name. Exported for tests.
|
|
31
|
+
*/
|
|
32
|
+
export declare function matchInstance(instances: Instance[], query: string): Instance | undefined;
|
|
2
33
|
export default class Auth extends Command {
|
|
3
34
|
static description: string;
|
|
35
|
+
static enableJsonFlag: boolean;
|
|
4
36
|
static examples: string[];
|
|
5
37
|
static flags: {
|
|
38
|
+
branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
39
|
+
code: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
40
|
config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
41
|
insecure: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
42
|
+
instance: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
43
|
'no-browser': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
44
|
origin: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
45
|
+
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
46
|
+
workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
47
|
};
|
|
11
|
-
run(): Promise<
|
|
48
|
+
run(): Promise<AuthResult>;
|
|
49
|
+
protected toErrorJson(err: unknown): unknown;
|
|
50
|
+
private acquireToken;
|
|
12
51
|
private getHeaders;
|
|
13
52
|
private fetchBranches;
|
|
14
53
|
private fetchInstances;
|
|
@@ -16,6 +55,11 @@ export default class Auth extends Command {
|
|
|
16
55
|
private promptForToken;
|
|
17
56
|
private promptProfileName;
|
|
18
57
|
private readTokenFromStdin;
|
|
58
|
+
private resolveBranch;
|
|
59
|
+
private resolveInstance;
|
|
60
|
+
private resolveProfileName;
|
|
61
|
+
private resolveWorkspace;
|
|
62
|
+
private resolveWorkspaceAndBranch;
|
|
19
63
|
private saveProfile;
|
|
20
64
|
private selectBranch;
|
|
21
65
|
private selectInstance;
|