@xano/cli 0.0.95-beta.2 → 0.0.95-beta.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/README.md +17 -9
- package/dist/base-command.d.ts +24 -0
- package/dist/base-command.js +37 -0
- package/dist/commands/auth/index.js +1 -1
- package/dist/commands/profile/me/index.js +21 -2
- package/dist/commands/profile/wizard/index.js +1 -1
- package/dist/commands/profile/workspace/set/index.js +1 -1
- package/dist/commands/{ephemeral → sandbox}/env/delete/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/delete/index.js +17 -33
- package/dist/commands/{ephemeral → sandbox}/env/get/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/get/index.js +13 -29
- package/dist/commands/{ephemeral → sandbox}/env/get_all/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/get_all/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/env/list/index.d.ts +1 -4
- package/dist/commands/sandbox/env/list/index.js +67 -0
- package/dist/commands/{ephemeral → sandbox}/env/set/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/set/index.js +14 -30
- package/dist/commands/{ephemeral → sandbox}/env/set_all/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/set_all/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/get/index.d.ts +1 -4
- package/dist/commands/sandbox/get/index.js +48 -0
- package/dist/commands/sandbox/impersonate/index.d.ts +5 -0
- package/dist/commands/sandbox/impersonate/index.js +5 -0
- package/dist/commands/{ephemeral → sandbox}/license/get/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/license/get/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/license/set/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/license/set/index.js +17 -33
- package/dist/commands/{ephemeral → sandbox}/pull/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/pull/index.js +11 -26
- package/dist/commands/{ephemeral → sandbox}/push/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/push/index.js +13 -28
- package/dist/commands/{ephemeral/delete → sandbox/reset}/index.d.ts +1 -5
- package/dist/commands/sandbox/reset/index.js +71 -0
- package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.d.ts +1 -4
- package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.js +15 -31
- package/dist/commands/{ephemeral/unit_test/run_all → sandbox/unit_test/list}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/list/index.js +10 -24
- package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.js +9 -23
- package/dist/commands/{ephemeral/unit_test/list → sandbox/unit_test/run_all}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/run_all/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/get → sandbox/workflow_test/delete}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/delete/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/run → sandbox/workflow_test/get}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/get/index.js +8 -25
- package/dist/commands/{ephemeral/workflow_test/run_all → sandbox/workflow_test/list}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/list/index.js +11 -25
- package/dist/commands/{ephemeral/workflow_test/delete → sandbox/workflow_test/run}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/run/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/list → sandbox/workflow_test/run_all}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/run_all/index.js +9 -23
- package/dist/commands/tenant/create/index.d.ts +2 -1
- package/dist/commands/tenant/create/index.js +23 -6
- package/dist/commands/tenant/get/index.js +2 -2
- package/dist/commands/tenant/list/index.js +2 -2
- package/dist/commands/tenant/push/index.js +0 -34
- package/dist/commands/workspace/edit/index.d.ts +1 -0
- package/dist/commands/workspace/edit/index.js +16 -6
- package/dist/commands/workspace/get/index.js +9 -7
- package/dist/commands/workspace/list/index.d.ts +1 -0
- package/dist/commands/workspace/list/index.js +14 -7
- package/dist/commands/workspace/push/index.js +26 -0
- package/oclif.manifest.json +1788 -2249
- package/package.json +7 -7
- package/dist/commands/ephemeral/access/index.d.ts +0 -15
- package/dist/commands/ephemeral/access/index.js +0 -78
- package/dist/commands/ephemeral/create/index.d.ts +0 -17
- package/dist/commands/ephemeral/create/index.js +0 -102
- package/dist/commands/ephemeral/delete/index.js +0 -99
- package/dist/commands/ephemeral/env/list/index.js +0 -83
- package/dist/commands/ephemeral/get/index.js +0 -102
- package/dist/commands/ephemeral/list/index.d.ts +0 -15
- package/dist/commands/ephemeral/list/index.js +0 -109
- package/dist/commands/ephemeral/shared/index.d.ts +0 -15
- package/dist/commands/ephemeral/shared/index.js +0 -108
package/README.md
CHANGED
|
@@ -307,7 +307,8 @@ xano tenant get <tenant_name>
|
|
|
307
307
|
|
|
308
308
|
# Create a tenant
|
|
309
309
|
xano tenant create "My Tenant"
|
|
310
|
-
xano tenant create "My Tenant" -d "Description" --cluster_id 1 --platform_id 5
|
|
310
|
+
xano tenant create "My Tenant" -d "Description" --type tier2 --cluster_id 1 --platform_id 5
|
|
311
|
+
xano tenant create "My Tenant" --type tier2 --cluster_id 1 --license ./license.yaml
|
|
311
312
|
|
|
312
313
|
# Edit a tenant
|
|
313
314
|
xano tenant edit <tenant_name> --display "New Name" -d "New description"
|
|
@@ -445,18 +446,25 @@ xano tenant cluster license set <cluster_id>
|
|
|
445
446
|
xano tenant cluster license set <cluster_id> --file ./kubeconfig.yaml
|
|
446
447
|
```
|
|
447
448
|
|
|
448
|
-
###
|
|
449
|
+
### Sandbox
|
|
449
450
|
|
|
450
|
-
Manage
|
|
451
|
+
Manage your sandbox tenant. Each user has a single sandbox tenant that is auto-provisioned on first use.
|
|
451
452
|
|
|
452
453
|
```bash
|
|
453
|
-
#
|
|
454
|
-
xano
|
|
455
|
-
xano
|
|
454
|
+
# Get your sandbox tenant (creates if needed)
|
|
455
|
+
xano sandbox get
|
|
456
|
+
xano sandbox get -o json
|
|
456
457
|
|
|
457
|
-
#
|
|
458
|
-
xano
|
|
459
|
-
xano
|
|
458
|
+
# Push/pull workspace data
|
|
459
|
+
xano sandbox push ./my-workspace
|
|
460
|
+
xano sandbox pull ./my-tenant
|
|
461
|
+
|
|
462
|
+
# Impersonate (open in browser)
|
|
463
|
+
xano sandbox impersonate
|
|
464
|
+
|
|
465
|
+
# Reset all workspace data
|
|
466
|
+
xano sandbox reset
|
|
467
|
+
xano sandbox reset --force
|
|
460
468
|
```
|
|
461
469
|
|
|
462
470
|
### Static Hosts
|
package/dist/base-command.d.ts
CHANGED
|
@@ -14,6 +14,16 @@ export interface CredentialsFile {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
export declare function buildUserAgent(version: string): string;
|
|
17
|
+
export interface SandboxTenant {
|
|
18
|
+
created_at?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
display?: string;
|
|
21
|
+
ephemeral?: boolean;
|
|
22
|
+
id: number;
|
|
23
|
+
name: string;
|
|
24
|
+
state?: string;
|
|
25
|
+
xano_domain?: string;
|
|
26
|
+
}
|
|
17
27
|
export default abstract class BaseCommand extends Command {
|
|
18
28
|
static baseFlags: {
|
|
19
29
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -38,6 +48,20 @@ export default abstract class BaseCommand extends Command {
|
|
|
38
48
|
* Load and parse the credentials file. Returns null if the file doesn't exist.
|
|
39
49
|
*/
|
|
40
50
|
protected loadCredentialsFile(): CredentialsFile | null;
|
|
51
|
+
/**
|
|
52
|
+
* Get or create the singleton sandbox environment for the authenticated user.
|
|
53
|
+
* Returns the sandbox object (existing or newly created).
|
|
54
|
+
*/
|
|
55
|
+
protected getOrCreateSandbox(profile: ProfileConfig, verbose: boolean): Promise<SandboxTenant>;
|
|
56
|
+
/**
|
|
57
|
+
* Resolve profile from flags, validating instance_origin and access_token exist.
|
|
58
|
+
*/
|
|
59
|
+
protected resolveProfile(flags: {
|
|
60
|
+
profile?: string;
|
|
61
|
+
}): {
|
|
62
|
+
profile: ProfileConfig;
|
|
63
|
+
profileName: string;
|
|
64
|
+
};
|
|
41
65
|
/**
|
|
42
66
|
* Make an HTTP request with optional verbose logging.
|
|
43
67
|
* Use this for all Metadata API calls to support the --verbose flag.
|
package/dist/base-command.js
CHANGED
|
@@ -103,6 +103,43 @@ export default class BaseCommand extends Command {
|
|
|
103
103
|
}
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Get or create the singleton sandbox environment for the authenticated user.
|
|
108
|
+
* Returns the sandbox object (existing or newly created).
|
|
109
|
+
*/
|
|
110
|
+
async getOrCreateSandbox(profile, verbose) {
|
|
111
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/me`;
|
|
112
|
+
const response = await this.verboseFetch(apiUrl, {
|
|
113
|
+
headers: {
|
|
114
|
+
accept: 'application/json',
|
|
115
|
+
Authorization: `Bearer ${profile.access_token}`,
|
|
116
|
+
},
|
|
117
|
+
method: 'GET',
|
|
118
|
+
}, verbose, profile.access_token);
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const errorText = await response.text();
|
|
121
|
+
this.error(`Failed to get sandbox environment: ${response.status} ${response.statusText}\n${errorText}`);
|
|
122
|
+
}
|
|
123
|
+
return (await response.json());
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resolve profile from flags, validating instance_origin and access_token exist.
|
|
127
|
+
*/
|
|
128
|
+
resolveProfile(flags) {
|
|
129
|
+
const profileName = flags.profile || this.getDefaultProfile();
|
|
130
|
+
const credentials = this.loadCredentialsFile();
|
|
131
|
+
if (!credentials || !(profileName in credentials.profiles)) {
|
|
132
|
+
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
133
|
+
}
|
|
134
|
+
const profile = credentials.profiles[profileName];
|
|
135
|
+
if (!profile.instance_origin) {
|
|
136
|
+
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
137
|
+
}
|
|
138
|
+
if (!profile.access_token) {
|
|
139
|
+
this.error(`Profile '${profileName}' is missing access_token`);
|
|
140
|
+
}
|
|
141
|
+
return { profile, profileName };
|
|
142
|
+
}
|
|
106
143
|
/**
|
|
107
144
|
* Make an HTTP request with optional verbose logging.
|
|
108
145
|
* Use this for all Metadata API calls to support the --verbose flag.
|
|
@@ -111,8 +111,27 @@ User Information:
|
|
|
111
111
|
this.log(` Name: ${inst.name}`);
|
|
112
112
|
if (inst.display)
|
|
113
113
|
this.log(` Display: ${inst.display}`);
|
|
114
|
-
if (profile.workspace)
|
|
115
|
-
|
|
114
|
+
if (profile.workspace) {
|
|
115
|
+
let wsLabel = String(profile.workspace);
|
|
116
|
+
try {
|
|
117
|
+
const wsResponse = await this.verboseFetch(`${profile.instance_origin}/api:meta/workspace/${profile.workspace}`, {
|
|
118
|
+
headers: {
|
|
119
|
+
accept: 'application/json',
|
|
120
|
+
Authorization: `Bearer ${profile.access_token}`,
|
|
121
|
+
},
|
|
122
|
+
method: 'GET',
|
|
123
|
+
}, false, profile.access_token);
|
|
124
|
+
if (wsResponse.ok) {
|
|
125
|
+
const ws = (await wsResponse.json());
|
|
126
|
+
if (ws.name)
|
|
127
|
+
wsLabel = `${ws.name} (ID: ${profile.workspace})`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Fall back to just showing the ID
|
|
132
|
+
}
|
|
133
|
+
this.log(` Workspace: ${wsLabel}`);
|
|
134
|
+
}
|
|
116
135
|
if (profile.branch)
|
|
117
136
|
this.log(` Branch: ${profile.branch}`);
|
|
118
137
|
}
|
|
@@ -40,7 +40,7 @@ Workspace updated to 'Production API' (xyz789) on profile 'production'
|
|
|
40
40
|
const { selectedWorkspace } = await inquirer.prompt([
|
|
41
41
|
{
|
|
42
42
|
choices: workspaces.map((ws) => ({
|
|
43
|
-
name: String(ws.id) === String(profile.workspace) ? `${ws.name} (current)` : ws.name
|
|
43
|
+
name: String(ws.id) === String(profile.workspace) ? `${ws.name} (${ws.id}) (current)` : `${ws.name} (${ws.id})`,
|
|
44
44
|
value: ws.id,
|
|
45
45
|
})),
|
|
46
46
|
message: 'Select a workspace',
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvDelete extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class
|
|
4
|
-
static
|
|
5
|
-
tenant_name: Args.string({
|
|
6
|
-
description: 'Ephemeral tenant name',
|
|
7
|
-
required: true,
|
|
8
|
-
}),
|
|
9
|
-
};
|
|
10
|
-
static description = 'Delete an environment variable from an ephemeral tenant';
|
|
3
|
+
export default class SandboxEnvDelete extends BaseCommand {
|
|
4
|
+
static description = 'Delete an environment variable from a sandbox environment';
|
|
11
5
|
static examples = [
|
|
12
|
-
`$ xano
|
|
13
|
-
Are you sure you want to delete environment variable 'DATABASE_URL'
|
|
14
|
-
Environment variable 'DATABASE_URL' deleted
|
|
6
|
+
`$ xano sandbox env delete --name DATABASE_URL
|
|
7
|
+
Are you sure you want to delete environment variable 'DATABASE_URL'? (y/N) y
|
|
8
|
+
Environment variable 'DATABASE_URL' deleted
|
|
15
9
|
`,
|
|
16
|
-
`$ xano
|
|
17
|
-
`$ xano
|
|
10
|
+
`$ xano sandbox env delete --name DATABASE_URL --force`,
|
|
11
|
+
`$ xano sandbox env delete --name DATABASE_URL -f -o json`,
|
|
18
12
|
];
|
|
19
13
|
static flags = {
|
|
20
14
|
...BaseCommand.baseFlags,
|
|
@@ -38,29 +32,19 @@ Environment variable 'DATABASE_URL' deleted from ephemeral tenant my-tenant
|
|
|
38
32
|
}),
|
|
39
33
|
};
|
|
40
34
|
async run() {
|
|
41
|
-
const {
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
46
|
-
}
|
|
47
|
-
const profile = credentials.profiles[profileName];
|
|
48
|
-
if (!profile.instance_origin) {
|
|
49
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
50
|
-
}
|
|
51
|
-
if (!profile.access_token) {
|
|
52
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
53
|
-
}
|
|
54
|
-
const tenantName = args.tenant_name;
|
|
35
|
+
const { flags } = await this.parse(SandboxEnvDelete);
|
|
36
|
+
const { profile } = this.resolveProfile(flags);
|
|
37
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
38
|
+
const tenantName = tenant.name;
|
|
55
39
|
const envName = flags.name;
|
|
56
40
|
if (!flags.force) {
|
|
57
|
-
const confirmed = await this.confirm(`Are you sure you want to delete environment variable '${envName}' from
|
|
41
|
+
const confirmed = await this.confirm(`Are you sure you want to delete environment variable '${envName}' from sandbox environment ${tenantName}?`);
|
|
58
42
|
if (!confirmed) {
|
|
59
43
|
this.log('Deletion cancelled.');
|
|
60
44
|
return;
|
|
61
45
|
}
|
|
62
46
|
}
|
|
63
|
-
const apiUrl = `${profile.instance_origin}/api:meta/
|
|
47
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/env/${envName}`;
|
|
64
48
|
try {
|
|
65
49
|
const response = await this.verboseFetch(apiUrl, {
|
|
66
50
|
headers: {
|
|
@@ -77,15 +61,15 @@ Environment variable 'DATABASE_URL' deleted from ephemeral tenant my-tenant
|
|
|
77
61
|
this.log(JSON.stringify({ deleted: true, env_name: envName, tenant_name: tenantName }, null, 2));
|
|
78
62
|
}
|
|
79
63
|
else {
|
|
80
|
-
this.log(`Environment variable '${envName}' deleted from
|
|
64
|
+
this.log(`Environment variable '${envName}' deleted from sandbox environment ${tenantName}`);
|
|
81
65
|
}
|
|
82
66
|
}
|
|
83
67
|
catch (error) {
|
|
84
68
|
if (error instanceof Error) {
|
|
85
|
-
this.error(`Failed to delete
|
|
69
|
+
this.error(`Failed to delete sandbox environment variable: ${error.message}`);
|
|
86
70
|
}
|
|
87
71
|
else {
|
|
88
|
-
this.error(`Failed to delete
|
|
72
|
+
this.error(`Failed to delete sandbox environment variable: ${String(error)}`);
|
|
89
73
|
}
|
|
90
74
|
}
|
|
91
75
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvGet extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class
|
|
4
|
-
static
|
|
5
|
-
tenant_name: Args.string({
|
|
6
|
-
description: 'Ephemeral tenant name',
|
|
7
|
-
required: true,
|
|
8
|
-
}),
|
|
9
|
-
};
|
|
10
|
-
static description = 'Get a single environment variable for an ephemeral tenant';
|
|
3
|
+
export default class SandboxEnvGet extends BaseCommand {
|
|
4
|
+
static description = 'Get a single environment variable for a sandbox environment';
|
|
11
5
|
static examples = [
|
|
12
|
-
`$ xano
|
|
6
|
+
`$ xano sandbox env get --name DATABASE_URL
|
|
13
7
|
postgres://localhost:5432/mydb
|
|
14
8
|
`,
|
|
15
|
-
`$ xano
|
|
9
|
+
`$ xano sandbox env get --name DATABASE_URL -o json`,
|
|
16
10
|
];
|
|
17
11
|
static flags = {
|
|
18
12
|
...BaseCommand.baseFlags,
|
|
@@ -30,22 +24,12 @@ postgres://localhost:5432/mydb
|
|
|
30
24
|
}),
|
|
31
25
|
};
|
|
32
26
|
async run() {
|
|
33
|
-
const {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
38
|
-
}
|
|
39
|
-
const profile = credentials.profiles[profileName];
|
|
40
|
-
if (!profile.instance_origin) {
|
|
41
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
42
|
-
}
|
|
43
|
-
if (!profile.access_token) {
|
|
44
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
45
|
-
}
|
|
46
|
-
const tenantName = args.tenant_name;
|
|
27
|
+
const { flags } = await this.parse(SandboxEnvGet);
|
|
28
|
+
const { profile } = this.resolveProfile(flags);
|
|
29
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
30
|
+
const tenantName = tenant.name;
|
|
47
31
|
const envName = flags.name;
|
|
48
|
-
const apiUrl = `${profile.instance_origin}/api:meta/
|
|
32
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/env/${envName}`;
|
|
49
33
|
try {
|
|
50
34
|
const response = await this.verboseFetch(apiUrl, {
|
|
51
35
|
headers: {
|
|
@@ -66,15 +50,15 @@ postgres://localhost:5432/mydb
|
|
|
66
50
|
this.log(envVar.value);
|
|
67
51
|
}
|
|
68
52
|
else {
|
|
69
|
-
this.log(`Environment variable '${envName}' not found for
|
|
53
|
+
this.log(`Environment variable '${envName}' not found for sandbox environment ${tenantName}`);
|
|
70
54
|
}
|
|
71
55
|
}
|
|
72
56
|
catch (error) {
|
|
73
57
|
if (error instanceof Error) {
|
|
74
|
-
this.error(`Failed to get
|
|
58
|
+
this.error(`Failed to get sandbox environment variable: ${error.message}`);
|
|
75
59
|
}
|
|
76
60
|
else {
|
|
77
|
-
this.error(`Failed to get
|
|
61
|
+
this.error(`Failed to get sandbox environment variable: ${String(error)}`);
|
|
78
62
|
}
|
|
79
63
|
}
|
|
80
64
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvGetAll extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,29 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import * as yaml from 'js-yaml';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import BaseCommand from '../../../../base-command.js';
|
|
6
|
-
export default class
|
|
7
|
-
static
|
|
8
|
-
tenant_name: Args.string({
|
|
9
|
-
description: 'Ephemeral tenant name',
|
|
10
|
-
required: true,
|
|
11
|
-
}),
|
|
12
|
-
};
|
|
13
|
-
static description = 'Get all environment variables for an ephemeral tenant and save to a YAML file';
|
|
6
|
+
export default class SandboxEnvGetAll extends BaseCommand {
|
|
7
|
+
static description = 'Get all environment variables for a sandbox environment and save to a YAML file';
|
|
14
8
|
static examples = [
|
|
15
|
-
`$ xano
|
|
16
|
-
Environment variables saved to
|
|
9
|
+
`$ xano sandbox env get_all
|
|
10
|
+
Environment variables saved to env_<tenant>.yaml
|
|
17
11
|
`,
|
|
18
|
-
`$ xano
|
|
19
|
-
`$ xano
|
|
20
|
-
`$ xano
|
|
12
|
+
`$ xano sandbox env get_all --file ./my-env.yaml`,
|
|
13
|
+
`$ xano sandbox env get_all --view`,
|
|
14
|
+
`$ xano sandbox env get_all -o json`,
|
|
21
15
|
];
|
|
22
16
|
static flags = {
|
|
23
17
|
...BaseCommand.baseFlags,
|
|
24
18
|
file: Flags.string({
|
|
25
19
|
char: 'f',
|
|
26
|
-
description: 'Output file path (default: env_<
|
|
20
|
+
description: 'Output file path (default: env_<sandbox_name>.yaml)',
|
|
27
21
|
required: false,
|
|
28
22
|
}),
|
|
29
23
|
output: Flags.string({
|
|
@@ -40,21 +34,11 @@ Environment variables saved to env_my-tenant.yaml
|
|
|
40
34
|
}),
|
|
41
35
|
};
|
|
42
36
|
async run() {
|
|
43
|
-
const {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const profile = credentials.profiles[profileName];
|
|
50
|
-
if (!profile.instance_origin) {
|
|
51
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
52
|
-
}
|
|
53
|
-
if (!profile.access_token) {
|
|
54
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
55
|
-
}
|
|
56
|
-
const tenantName = args.tenant_name;
|
|
57
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/env_all`;
|
|
37
|
+
const { flags } = await this.parse(SandboxEnvGetAll);
|
|
38
|
+
const { profile } = this.resolveProfile(flags);
|
|
39
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
40
|
+
const tenantName = tenant.name;
|
|
41
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/env_all`;
|
|
58
42
|
try {
|
|
59
43
|
const response = await this.verboseFetch(apiUrl, {
|
|
60
44
|
headers: {
|
|
@@ -84,10 +68,10 @@ Environment variables saved to env_my-tenant.yaml
|
|
|
84
68
|
}
|
|
85
69
|
catch (error) {
|
|
86
70
|
if (error instanceof Error) {
|
|
87
|
-
this.error(`Failed to get
|
|
71
|
+
this.error(`Failed to get sandbox environment variables: ${error.message}`);
|
|
88
72
|
}
|
|
89
73
|
else {
|
|
90
|
-
this.error(`Failed to get
|
|
74
|
+
this.error(`Failed to get sandbox environment variables: ${String(error)}`);
|
|
91
75
|
}
|
|
92
76
|
}
|
|
93
77
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvList extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import BaseCommand from '../../../../base-command.js';
|
|
3
|
+
export default class SandboxEnvList extends BaseCommand {
|
|
4
|
+
static description = 'List environment variable keys for a sandbox environment';
|
|
5
|
+
static examples = [
|
|
6
|
+
`$ xano sandbox env list
|
|
7
|
+
Environment variables for sandbox environment:
|
|
8
|
+
- DATABASE_URL
|
|
9
|
+
- API_KEY
|
|
10
|
+
`,
|
|
11
|
+
`$ xano sandbox env list -o json`,
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
...BaseCommand.baseFlags,
|
|
15
|
+
output: Flags.string({
|
|
16
|
+
char: 'o',
|
|
17
|
+
default: 'summary',
|
|
18
|
+
description: 'Output format',
|
|
19
|
+
options: ['summary', 'json'],
|
|
20
|
+
required: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags } = await this.parse(SandboxEnvList);
|
|
25
|
+
const { profile } = this.resolveProfile(flags);
|
|
26
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
27
|
+
const tenantName = tenant.name;
|
|
28
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/env_key`;
|
|
29
|
+
try {
|
|
30
|
+
const response = await this.verboseFetch(apiUrl, {
|
|
31
|
+
headers: {
|
|
32
|
+
accept: 'application/json',
|
|
33
|
+
Authorization: `Bearer ${profile.access_token}`,
|
|
34
|
+
},
|
|
35
|
+
method: 'GET',
|
|
36
|
+
}, flags.verbose, profile.access_token);
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const errorText = await response.text();
|
|
39
|
+
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
40
|
+
}
|
|
41
|
+
const data = (await response.json());
|
|
42
|
+
if (flags.output === 'json') {
|
|
43
|
+
this.log(JSON.stringify(data, null, 2));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const envVars = data.env || [];
|
|
47
|
+
if (envVars.length === 0) {
|
|
48
|
+
this.log(`No environment variables found for sandbox environment ${tenantName}`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.log(`Environment variables for sandbox environment ${tenantName}:`);
|
|
52
|
+
for (const envVar of envVars) {
|
|
53
|
+
this.log(` - ${envVar.name}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error instanceof Error) {
|
|
60
|
+
this.error(`Failed to list sandbox environment variables: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.error(`Failed to list sandbox environment variables: ${String(error)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvSet extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class
|
|
4
|
-
static
|
|
5
|
-
tenant_name: Args.string({
|
|
6
|
-
description: 'Ephemeral tenant name',
|
|
7
|
-
required: true,
|
|
8
|
-
}),
|
|
9
|
-
};
|
|
10
|
-
static description = 'Set (create or update) an environment variable for an ephemeral tenant';
|
|
3
|
+
export default class SandboxEnvSet extends BaseCommand {
|
|
4
|
+
static description = 'Set (create or update) an environment variable for a sandbox environment';
|
|
11
5
|
static examples = [
|
|
12
|
-
`$ xano
|
|
13
|
-
Environment variable 'DATABASE_URL' set
|
|
6
|
+
`$ xano sandbox env set --name DATABASE_URL --value postgres://localhost:5432/mydb
|
|
7
|
+
Environment variable 'DATABASE_URL' set
|
|
14
8
|
`,
|
|
15
|
-
`$ xano
|
|
9
|
+
`$ xano sandbox env set --name DATABASE_URL --value postgres://localhost:5432/mydb -o json`,
|
|
16
10
|
];
|
|
17
11
|
static flags = {
|
|
18
12
|
...BaseCommand.baseFlags,
|
|
@@ -34,22 +28,12 @@ Environment variable 'DATABASE_URL' set for ephemeral tenant my-tenant
|
|
|
34
28
|
}),
|
|
35
29
|
};
|
|
36
30
|
async run() {
|
|
37
|
-
const {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
42
|
-
}
|
|
43
|
-
const profile = credentials.profiles[profileName];
|
|
44
|
-
if (!profile.instance_origin) {
|
|
45
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
46
|
-
}
|
|
47
|
-
if (!profile.access_token) {
|
|
48
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
49
|
-
}
|
|
50
|
-
const tenantName = args.tenant_name;
|
|
31
|
+
const { flags } = await this.parse(SandboxEnvSet);
|
|
32
|
+
const { profile } = this.resolveProfile(flags);
|
|
33
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
34
|
+
const tenantName = tenant.name;
|
|
51
35
|
const envName = flags.name;
|
|
52
|
-
const apiUrl = `${profile.instance_origin}/api:meta/
|
|
36
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/env/${envName}`;
|
|
53
37
|
const body = {
|
|
54
38
|
env: {
|
|
55
39
|
name: envName,
|
|
@@ -75,15 +59,15 @@ Environment variable 'DATABASE_URL' set for ephemeral tenant my-tenant
|
|
|
75
59
|
this.log(JSON.stringify(result, null, 2));
|
|
76
60
|
}
|
|
77
61
|
else {
|
|
78
|
-
this.log(`Environment variable '${envName}' set for
|
|
62
|
+
this.log(`Environment variable '${envName}' set for sandbox environment ${tenantName}`);
|
|
79
63
|
}
|
|
80
64
|
}
|
|
81
65
|
catch (error) {
|
|
82
66
|
if (error instanceof Error) {
|
|
83
|
-
this.error(`Failed to set
|
|
67
|
+
this.error(`Failed to set sandbox environment variable: ${error.message}`);
|
|
84
68
|
}
|
|
85
69
|
else {
|
|
86
|
-
this.error(`Failed to set
|
|
70
|
+
this.error(`Failed to set sandbox environment variable: ${String(error)}`);
|
|
87
71
|
}
|
|
88
72
|
}
|
|
89
73
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxEnvSetAll extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|