@xano/cli 0.0.95-beta.2 → 0.0.95
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 +2 -20
- package/dist/commands/tenant/create/index.d.ts +3 -1
- package/dist/commands/tenant/create/index.js +28 -6
- package/dist/commands/tenant/push/index.js +1 -1
- package/dist/help.d.ts +1 -2
- package/dist/help.js +1 -39
- package/oclif.manifest.json +2251 -5131
- package/package.json +1 -16
- 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.d.ts +0 -16
- package/dist/commands/ephemeral/delete/index.js +0 -99
- package/dist/commands/ephemeral/env/delete/index.d.ts +0 -17
- package/dist/commands/ephemeral/env/delete/index.js +0 -105
- package/dist/commands/ephemeral/env/get/index.d.ts +0 -15
- package/dist/commands/ephemeral/env/get/index.js +0 -81
- package/dist/commands/ephemeral/env/get_all/index.d.ts +0 -16
- package/dist/commands/ephemeral/env/get_all/index.js +0 -94
- package/dist/commands/ephemeral/env/list/index.d.ts +0 -14
- package/dist/commands/ephemeral/env/list/index.js +0 -83
- package/dist/commands/ephemeral/env/set/index.d.ts +0 -16
- package/dist/commands/ephemeral/env/set/index.js +0 -90
- package/dist/commands/ephemeral/env/set_all/index.d.ts +0 -16
- package/dist/commands/ephemeral/env/set_all/index.js +0 -102
- package/dist/commands/ephemeral/get/index.d.ts +0 -14
- package/dist/commands/ephemeral/get/index.js +0 -102
- package/dist/commands/ephemeral/impersonate/index.d.ts +0 -16
- package/dist/commands/ephemeral/impersonate/index.js +0 -110
- package/dist/commands/ephemeral/license/get/index.d.ts +0 -16
- package/dist/commands/ephemeral/license/get/index.js +0 -94
- package/dist/commands/ephemeral/license/set/index.d.ts +0 -17
- package/dist/commands/ephemeral/license/set/index.js +0 -111
- package/dist/commands/ephemeral/list/index.d.ts +0 -15
- package/dist/commands/ephemeral/list/index.js +0 -109
- package/dist/commands/ephemeral/pull/index.d.ts +0 -18
- package/dist/commands/ephemeral/pull/index.js +0 -197
- package/dist/commands/ephemeral/push/index.d.ts +0 -19
- package/dist/commands/ephemeral/push/index.js +0 -158
- package/dist/commands/ephemeral/shared/index.d.ts +0 -15
- package/dist/commands/ephemeral/shared/index.js +0 -108
- package/dist/commands/ephemeral/unit_test/list/index.d.ts +0 -14
- package/dist/commands/ephemeral/unit_test/list/index.js +0 -105
- package/dist/commands/ephemeral/unit_test/run/index.d.ts +0 -15
- package/dist/commands/ephemeral/unit_test/run/index.js +0 -93
- package/dist/commands/ephemeral/unit_test/run_all/index.d.ts +0 -14
- package/dist/commands/ephemeral/unit_test/run_all/index.js +0 -183
- package/dist/commands/ephemeral/workflow_test/delete/index.d.ts +0 -18
- package/dist/commands/ephemeral/workflow_test/delete/index.js +0 -75
- package/dist/commands/ephemeral/workflow_test/get/index.d.ts +0 -18
- package/dist/commands/ephemeral/workflow_test/get/index.js +0 -77
- package/dist/commands/ephemeral/workflow_test/list/index.d.ts +0 -13
- package/dist/commands/ephemeral/workflow_test/list/index.js +0 -98
- package/dist/commands/ephemeral/workflow_test/run/index.d.ts +0 -18
- package/dist/commands/ephemeral/workflow_test/run/index.js +0 -91
- package/dist/commands/ephemeral/workflow_test/run_all/index.d.ts +0 -13
- package/dist/commands/ephemeral/workflow_test/run_all/index.js +0 -169
- package/dist/commands/release/deploy/index.d.ts +0 -17
- package/dist/commands/release/deploy/index.js +0 -107
- package/dist/commands/tenant/unit_test/list/index.d.ts +0 -15
- package/dist/commands/tenant/unit_test/list/index.js +0 -140
- package/dist/commands/tenant/unit_test/run/index.d.ts +0 -16
- package/dist/commands/tenant/unit_test/run/index.js +0 -128
- package/dist/commands/tenant/unit_test/run_all/index.d.ts +0 -15
- package/dist/commands/tenant/unit_test/run_all/index.js +0 -215
- package/dist/commands/tenant/workflow_test/delete/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/delete/index.js +0 -110
- package/dist/commands/tenant/workflow_test/get/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/get/index.js +0 -112
- package/dist/commands/tenant/workflow_test/list/index.d.ts +0 -14
- package/dist/commands/tenant/workflow_test/list/index.js +0 -133
- package/dist/commands/tenant/workflow_test/run/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/run/index.js +0 -126
- package/dist/commands/tenant/workflow_test/run_all/index.d.ts +0 -14
- package/dist/commands/tenant/workflow_test/run_all/index.js +0 -201
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import BaseCommand from '../../../../base-command.js';
|
|
6
|
-
export default class EphemeralEnvGetAll extends BaseCommand {
|
|
7
|
-
static args = {
|
|
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';
|
|
14
|
-
static examples = [
|
|
15
|
-
`$ xano ephemeral env get_all my-tenant
|
|
16
|
-
Environment variables saved to env_my-tenant.yaml
|
|
17
|
-
`,
|
|
18
|
-
`$ xano ephemeral env get_all my-tenant --file ./my-env.yaml`,
|
|
19
|
-
`$ xano ephemeral env get_all my-tenant --view`,
|
|
20
|
-
`$ xano ephemeral env get_all my-tenant -o json`,
|
|
21
|
-
];
|
|
22
|
-
static flags = {
|
|
23
|
-
...BaseCommand.baseFlags,
|
|
24
|
-
file: Flags.string({
|
|
25
|
-
char: 'f',
|
|
26
|
-
description: 'Output file path (default: env_<tenant_name>.yaml)',
|
|
27
|
-
required: false,
|
|
28
|
-
}),
|
|
29
|
-
output: Flags.string({
|
|
30
|
-
char: 'o',
|
|
31
|
-
default: 'summary',
|
|
32
|
-
description: 'Output format',
|
|
33
|
-
options: ['summary', 'json'],
|
|
34
|
-
required: false,
|
|
35
|
-
}),
|
|
36
|
-
view: Flags.boolean({
|
|
37
|
-
default: false,
|
|
38
|
-
description: 'Print environment variables to stdout instead of saving to file',
|
|
39
|
-
required: false,
|
|
40
|
-
}),
|
|
41
|
-
};
|
|
42
|
-
async run() {
|
|
43
|
-
const { args, flags } = await this.parse(EphemeralEnvGetAll);
|
|
44
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
45
|
-
const credentials = this.loadCredentialsFile();
|
|
46
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
47
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
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`;
|
|
58
|
-
try {
|
|
59
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
60
|
-
headers: {
|
|
61
|
-
accept: 'application/json',
|
|
62
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
63
|
-
},
|
|
64
|
-
method: 'GET',
|
|
65
|
-
}, flags.verbose, profile.access_token);
|
|
66
|
-
if (!response.ok) {
|
|
67
|
-
const errorText = await response.text();
|
|
68
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
69
|
-
}
|
|
70
|
-
const envMap = (await response.json());
|
|
71
|
-
if (flags.output === 'json') {
|
|
72
|
-
this.log(JSON.stringify(envMap, null, 2));
|
|
73
|
-
}
|
|
74
|
-
else if (flags.view) {
|
|
75
|
-
const envYaml = yaml.dump(envMap, { lineWidth: -1, sortKeys: true });
|
|
76
|
-
this.log(envYaml.trimEnd());
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
const filePath = path.resolve(flags.file || `env_${tenantName}.yaml`);
|
|
80
|
-
const envYaml = yaml.dump(envMap, { lineWidth: -1, sortKeys: true });
|
|
81
|
-
fs.writeFileSync(filePath, envYaml, 'utf8');
|
|
82
|
-
this.log(`Environment variables saved to ${filePath}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
if (error instanceof Error) {
|
|
87
|
-
this.error(`Failed to get ephemeral tenant environment variables: ${error.message}`);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.error(`Failed to get ephemeral tenant environment variables: ${String(error)}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class EphemeralEnvList extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<void>;
|
|
14
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class EphemeralEnvList extends BaseCommand {
|
|
4
|
-
static args = {
|
|
5
|
-
tenant_name: Args.string({
|
|
6
|
-
description: 'Ephemeral tenant name',
|
|
7
|
-
required: true,
|
|
8
|
-
}),
|
|
9
|
-
};
|
|
10
|
-
static description = 'List environment variable keys for an ephemeral tenant';
|
|
11
|
-
static examples = [
|
|
12
|
-
`$ xano ephemeral env list my-tenant
|
|
13
|
-
Environment variables for ephemeral tenant my-tenant:
|
|
14
|
-
- DATABASE_URL
|
|
15
|
-
- API_KEY
|
|
16
|
-
`,
|
|
17
|
-
`$ xano ephemeral env list my-tenant -o json`,
|
|
18
|
-
];
|
|
19
|
-
static flags = {
|
|
20
|
-
...BaseCommand.baseFlags,
|
|
21
|
-
output: Flags.string({
|
|
22
|
-
char: 'o',
|
|
23
|
-
default: 'summary',
|
|
24
|
-
description: 'Output format',
|
|
25
|
-
options: ['summary', 'json'],
|
|
26
|
-
required: false,
|
|
27
|
-
}),
|
|
28
|
-
};
|
|
29
|
-
async run() {
|
|
30
|
-
const { args, flags } = await this.parse(EphemeralEnvList);
|
|
31
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
32
|
-
const credentials = this.loadCredentialsFile();
|
|
33
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
34
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
35
|
-
}
|
|
36
|
-
const profile = credentials.profiles[profileName];
|
|
37
|
-
if (!profile.instance_origin) {
|
|
38
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
39
|
-
}
|
|
40
|
-
if (!profile.access_token) {
|
|
41
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
42
|
-
}
|
|
43
|
-
const tenantName = args.tenant_name;
|
|
44
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/env_key`;
|
|
45
|
-
try {
|
|
46
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
47
|
-
headers: {
|
|
48
|
-
accept: 'application/json',
|
|
49
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
50
|
-
},
|
|
51
|
-
method: 'GET',
|
|
52
|
-
}, flags.verbose, profile.access_token);
|
|
53
|
-
if (!response.ok) {
|
|
54
|
-
const errorText = await response.text();
|
|
55
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
56
|
-
}
|
|
57
|
-
const data = (await response.json());
|
|
58
|
-
if (flags.output === 'json') {
|
|
59
|
-
this.log(JSON.stringify(data, null, 2));
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const envVars = data.env || [];
|
|
63
|
-
if (envVars.length === 0) {
|
|
64
|
-
this.log(`No environment variables found for ephemeral tenant ${tenantName}`);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
this.log(`Environment variables for ephemeral tenant ${tenantName}:`);
|
|
68
|
-
for (const envVar of envVars) {
|
|
69
|
-
this.log(` - ${envVar.name}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
if (error instanceof Error) {
|
|
76
|
-
this.error(`Failed to list ephemeral tenant environment variables: ${error.message}`);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
this.error(`Failed to list ephemeral tenant environment variables: ${String(error)}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class EphemeralEnvSet extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
value: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
};
|
|
15
|
-
run(): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class EphemeralEnvSet extends BaseCommand {
|
|
4
|
-
static args = {
|
|
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';
|
|
11
|
-
static examples = [
|
|
12
|
-
`$ xano ephemeral env set my-tenant --name DATABASE_URL --value postgres://localhost:5432/mydb
|
|
13
|
-
Environment variable 'DATABASE_URL' set for ephemeral tenant my-tenant
|
|
14
|
-
`,
|
|
15
|
-
`$ xano ephemeral env set my-tenant --name DATABASE_URL --value postgres://localhost:5432/mydb -o json`,
|
|
16
|
-
];
|
|
17
|
-
static flags = {
|
|
18
|
-
...BaseCommand.baseFlags,
|
|
19
|
-
name: Flags.string({
|
|
20
|
-
char: 'n',
|
|
21
|
-
description: 'Environment variable name',
|
|
22
|
-
required: true,
|
|
23
|
-
}),
|
|
24
|
-
output: Flags.string({
|
|
25
|
-
char: 'o',
|
|
26
|
-
default: 'summary',
|
|
27
|
-
description: 'Output format',
|
|
28
|
-
options: ['summary', 'json'],
|
|
29
|
-
required: false,
|
|
30
|
-
}),
|
|
31
|
-
value: Flags.string({
|
|
32
|
-
description: 'Environment variable value',
|
|
33
|
-
required: true,
|
|
34
|
-
}),
|
|
35
|
-
};
|
|
36
|
-
async run() {
|
|
37
|
-
const { args, flags } = await this.parse(EphemeralEnvSet);
|
|
38
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
39
|
-
const credentials = this.loadCredentialsFile();
|
|
40
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
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;
|
|
51
|
-
const envName = flags.name;
|
|
52
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/env/${envName}`;
|
|
53
|
-
const body = {
|
|
54
|
-
env: {
|
|
55
|
-
name: envName,
|
|
56
|
-
value: flags.value,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
try {
|
|
60
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
61
|
-
body: JSON.stringify(body),
|
|
62
|
-
headers: {
|
|
63
|
-
accept: 'application/json',
|
|
64
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
65
|
-
'Content-Type': 'application/json',
|
|
66
|
-
},
|
|
67
|
-
method: 'PATCH',
|
|
68
|
-
}, flags.verbose, profile.access_token);
|
|
69
|
-
if (!response.ok) {
|
|
70
|
-
const errorText = await response.text();
|
|
71
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
72
|
-
}
|
|
73
|
-
if (flags.output === 'json') {
|
|
74
|
-
const result = await response.json();
|
|
75
|
-
this.log(JSON.stringify(result, null, 2));
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
this.log(`Environment variable '${envName}' set for ephemeral tenant ${tenantName}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
if (error instanceof Error) {
|
|
83
|
-
this.error(`Failed to set ephemeral tenant environment variable: ${error.message}`);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
this.error(`Failed to set ephemeral tenant environment variable: ${String(error)}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class EphemeralEnvSetAll extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
clean: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
};
|
|
15
|
-
run(): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import BaseCommand from '../../../../base-command.js';
|
|
6
|
-
export default class EphemeralEnvSetAll extends BaseCommand {
|
|
7
|
-
static args = {
|
|
8
|
-
tenant_name: Args.string({
|
|
9
|
-
description: 'Ephemeral tenant name',
|
|
10
|
-
required: true,
|
|
11
|
-
}),
|
|
12
|
-
};
|
|
13
|
-
static description = 'Set all environment variables for an ephemeral tenant from a YAML file (replaces all existing)';
|
|
14
|
-
static examples = [
|
|
15
|
-
`$ xano ephemeral env set_all my-tenant
|
|
16
|
-
Reads from env_my-tenant.yaml
|
|
17
|
-
`,
|
|
18
|
-
`$ xano ephemeral env set_all my-tenant --file ./my-env.yaml`,
|
|
19
|
-
`$ xano ephemeral env set_all my-tenant -o json`,
|
|
20
|
-
];
|
|
21
|
-
static flags = {
|
|
22
|
-
...BaseCommand.baseFlags,
|
|
23
|
-
clean: Flags.boolean({
|
|
24
|
-
default: false,
|
|
25
|
-
description: 'Remove the source file after successful upload',
|
|
26
|
-
required: false,
|
|
27
|
-
}),
|
|
28
|
-
file: Flags.string({
|
|
29
|
-
char: 'f',
|
|
30
|
-
description: 'Path to env file (default: env_<tenant_name>.yaml)',
|
|
31
|
-
required: false,
|
|
32
|
-
}),
|
|
33
|
-
output: Flags.string({
|
|
34
|
-
char: 'o',
|
|
35
|
-
default: 'summary',
|
|
36
|
-
description: 'Output format',
|
|
37
|
-
options: ['summary', 'json'],
|
|
38
|
-
required: false,
|
|
39
|
-
}),
|
|
40
|
-
};
|
|
41
|
-
async run() {
|
|
42
|
-
const { args, flags } = await this.parse(EphemeralEnvSetAll);
|
|
43
|
-
const tenantName = args.tenant_name;
|
|
44
|
-
const sourceFilePath = path.resolve(flags.file || `env_${tenantName}.yaml`);
|
|
45
|
-
if (!fs.existsSync(sourceFilePath)) {
|
|
46
|
-
this.error(`File not found: ${sourceFilePath}`);
|
|
47
|
-
}
|
|
48
|
-
const fileContent = fs.readFileSync(sourceFilePath, 'utf8');
|
|
49
|
-
const envMap = yaml.load(fileContent);
|
|
50
|
-
if (!envMap || typeof envMap !== 'object') {
|
|
51
|
-
this.error('Invalid env file format. Expected a YAML map of key: value pairs.');
|
|
52
|
-
}
|
|
53
|
-
const envs = Object.entries(envMap).map(([name, value]) => ({ name, value: String(value) }));
|
|
54
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
55
|
-
const credentials = this.loadCredentialsFile();
|
|
56
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
57
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
58
|
-
}
|
|
59
|
-
const profile = credentials.profiles[profileName];
|
|
60
|
-
if (!profile.instance_origin) {
|
|
61
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
62
|
-
}
|
|
63
|
-
if (!profile.access_token) {
|
|
64
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
65
|
-
}
|
|
66
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/env_all`;
|
|
67
|
-
try {
|
|
68
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
69
|
-
body: JSON.stringify({ envs }),
|
|
70
|
-
headers: {
|
|
71
|
-
accept: 'application/json',
|
|
72
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
73
|
-
'Content-Type': 'application/json',
|
|
74
|
-
},
|
|
75
|
-
method: 'PUT',
|
|
76
|
-
}, flags.verbose, profile.access_token);
|
|
77
|
-
if (!response.ok) {
|
|
78
|
-
const errorText = await response.text();
|
|
79
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
80
|
-
}
|
|
81
|
-
if (flags.output === 'json') {
|
|
82
|
-
const result = await response.json();
|
|
83
|
-
this.log(JSON.stringify(result, null, 2));
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
this.log(`All environment variables updated for ephemeral tenant ${tenantName} (${envs.length} variables)`);
|
|
87
|
-
}
|
|
88
|
-
if (flags.clean && fs.existsSync(sourceFilePath)) {
|
|
89
|
-
fs.unlinkSync(sourceFilePath);
|
|
90
|
-
this.log(`Removed ${sourceFilePath}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
if (error instanceof Error) {
|
|
95
|
-
this.error(`Failed to set ephemeral tenant environment variables: ${error.message}`);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
this.error(`Failed to set ephemeral tenant environment variables: ${String(error)}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class EphemeralGet extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<void>;
|
|
14
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import BaseCommand from '../../../base-command.js';
|
|
3
|
-
export default class EphemeralGet extends BaseCommand {
|
|
4
|
-
static args = {
|
|
5
|
-
tenant_name: Args.string({
|
|
6
|
-
description: 'Ephemeral tenant name to retrieve',
|
|
7
|
-
required: true,
|
|
8
|
-
}),
|
|
9
|
-
};
|
|
10
|
-
static description = 'Get details of an ephemeral tenant';
|
|
11
|
-
static examples = [
|
|
12
|
-
`$ xano ephemeral get t1234-abcd-xyz1
|
|
13
|
-
Ephemeral Tenant: My Tenant (my-tenant)
|
|
14
|
-
State: ok
|
|
15
|
-
License: tier1
|
|
16
|
-
Domain: my-tenant.xano.io
|
|
17
|
-
`,
|
|
18
|
-
`$ xano ephemeral get t1234-abcd-xyz1 -o json`,
|
|
19
|
-
];
|
|
20
|
-
static flags = {
|
|
21
|
-
...BaseCommand.baseFlags,
|
|
22
|
-
output: Flags.string({
|
|
23
|
-
char: 'o',
|
|
24
|
-
default: 'summary',
|
|
25
|
-
description: 'Output format',
|
|
26
|
-
options: ['summary', 'json'],
|
|
27
|
-
required: false,
|
|
28
|
-
}),
|
|
29
|
-
};
|
|
30
|
-
async run() {
|
|
31
|
-
const { args, flags } = await this.parse(EphemeralGet);
|
|
32
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
33
|
-
const credentials = this.loadCredentialsFile();
|
|
34
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
35
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
36
|
-
}
|
|
37
|
-
const profile = credentials.profiles[profileName];
|
|
38
|
-
if (!profile.instance_origin) {
|
|
39
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
40
|
-
}
|
|
41
|
-
if (!profile.access_token) {
|
|
42
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
43
|
-
}
|
|
44
|
-
const tenantName = args.tenant_name;
|
|
45
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}`;
|
|
46
|
-
try {
|
|
47
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
48
|
-
headers: {
|
|
49
|
-
accept: 'application/json',
|
|
50
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
51
|
-
},
|
|
52
|
-
method: 'GET',
|
|
53
|
-
}, flags.verbose, profile.access_token);
|
|
54
|
-
if (!response.ok) {
|
|
55
|
-
const errorText = await response.text();
|
|
56
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
57
|
-
}
|
|
58
|
-
const tenant = (await response.json());
|
|
59
|
-
if (flags.output === 'json') {
|
|
60
|
-
this.log(JSON.stringify(tenant, null, 2));
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
this.log(`Ephemeral Tenant: ${tenant.display || tenant.name} (${tenant.name})`);
|
|
64
|
-
if (tenant.state)
|
|
65
|
-
this.log(` State: ${tenant.state}`);
|
|
66
|
-
if (tenant.ephemeral_access)
|
|
67
|
-
this.log(` Access: ${tenant.ephemeral_access}`);
|
|
68
|
-
if (tenant.license)
|
|
69
|
-
this.log(` License: ${tenant.license}`);
|
|
70
|
-
if (tenant.xano_domain)
|
|
71
|
-
this.log(` Domain: ${tenant.xano_domain}`);
|
|
72
|
-
if (tenant.domain)
|
|
73
|
-
this.log(` Custom Domain: ${tenant.domain}`);
|
|
74
|
-
if (tenant.cluster?.name)
|
|
75
|
-
this.log(` Cluster: ${tenant.cluster.name}`);
|
|
76
|
-
const releaseName = typeof tenant.release === 'string' ? tenant.release : tenant.release?.name;
|
|
77
|
-
const releaseId = typeof tenant.release === 'object' ? tenant.release?.id : undefined;
|
|
78
|
-
if (releaseName)
|
|
79
|
-
this.log(` Release: ${releaseName} (ID: ${releaseId})`);
|
|
80
|
-
if (tenant.platform?.name)
|
|
81
|
-
this.log(` Platform: ${tenant.platform.name}`);
|
|
82
|
-
if (tenant.version !== undefined)
|
|
83
|
-
this.log(` Version: ${tenant.version}`);
|
|
84
|
-
if (tenant.ingress !== undefined)
|
|
85
|
-
this.log(` Ingress: ${tenant.ingress}`);
|
|
86
|
-
if (tenant.deployed_at) {
|
|
87
|
-
const d = new Date(tenant.deployed_at);
|
|
88
|
-
const deployedDate = Number.isNaN(d.getTime()) ? tenant.deployed_at : d.toISOString().split('T')[0];
|
|
89
|
-
this.log(` Deployed: ${deployedDate}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
if (error instanceof Error) {
|
|
95
|
-
this.error(`Failed to get ephemeral tenant: ${error.message}`);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
this.error(`Failed to get ephemeral tenant: ${String(error)}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class EphemeralImpersonate extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
'url-only': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
};
|
|
14
|
-
run(): Promise<void>;
|
|
15
|
-
private getFrontendUrl;
|
|
16
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import open from 'open';
|
|
3
|
-
import BaseCommand from '../../../base-command.js';
|
|
4
|
-
export default class EphemeralImpersonate extends BaseCommand {
|
|
5
|
-
static args = {
|
|
6
|
-
tenant_name: Args.string({
|
|
7
|
-
description: 'Ephemeral tenant name to impersonate',
|
|
8
|
-
required: true,
|
|
9
|
-
}),
|
|
10
|
-
};
|
|
11
|
-
static description = 'Impersonate an ephemeral tenant and open it in the browser';
|
|
12
|
-
static examples = [
|
|
13
|
-
`$ xano ephemeral impersonate my-tenant
|
|
14
|
-
Opening browser...
|
|
15
|
-
Impersonation successful!
|
|
16
|
-
`,
|
|
17
|
-
`$ xano ephemeral impersonate my-tenant -u`,
|
|
18
|
-
`$ xano ephemeral impersonate my-tenant -o json`,
|
|
19
|
-
];
|
|
20
|
-
static flags = {
|
|
21
|
-
...BaseCommand.baseFlags,
|
|
22
|
-
output: Flags.string({
|
|
23
|
-
char: 'o',
|
|
24
|
-
default: 'summary',
|
|
25
|
-
description: 'Output format',
|
|
26
|
-
options: ['summary', 'json'],
|
|
27
|
-
required: false,
|
|
28
|
-
}),
|
|
29
|
-
'url-only': Flags.boolean({
|
|
30
|
-
char: 'u',
|
|
31
|
-
default: false,
|
|
32
|
-
description: 'Print the URL without opening the browser',
|
|
33
|
-
required: false,
|
|
34
|
-
}),
|
|
35
|
-
};
|
|
36
|
-
async run() {
|
|
37
|
-
const { args, flags } = await this.parse(EphemeralImpersonate);
|
|
38
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
39
|
-
const credentials = this.loadCredentialsFile();
|
|
40
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
41
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano auth'`);
|
|
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;
|
|
51
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(tenantName)}/impersonate`;
|
|
52
|
-
try {
|
|
53
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
54
|
-
headers: {
|
|
55
|
-
accept: 'application/json',
|
|
56
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
57
|
-
},
|
|
58
|
-
method: 'GET',
|
|
59
|
-
}, flags.verbose, profile.access_token);
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
const errorText = await response.text();
|
|
62
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
63
|
-
}
|
|
64
|
-
const result = (await response.json());
|
|
65
|
-
if (!result._ti) {
|
|
66
|
-
this.error('No one-time token returned from impersonate API');
|
|
67
|
-
}
|
|
68
|
-
if (flags.output === 'json') {
|
|
69
|
-
this.log(JSON.stringify(result, null, 2));
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
const frontendUrl = this.getFrontendUrl(profile.instance_origin);
|
|
73
|
-
const params = new URLSearchParams({
|
|
74
|
-
_ti: result._ti,
|
|
75
|
-
});
|
|
76
|
-
const impersonateUrl = `${frontendUrl}/impersonate?${params.toString()}`;
|
|
77
|
-
if (flags['url-only']) {
|
|
78
|
-
this.log(impersonateUrl);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
this.log('Opening browser...');
|
|
82
|
-
await open(impersonateUrl);
|
|
83
|
-
this.log('Impersonation successful!');
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
process.exit(0);
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
if (error instanceof Error) {
|
|
90
|
-
this.error(`Failed to impersonate ephemeral tenant: ${error.message}`);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
this.error(`Failed to impersonate ephemeral tenant: ${String(error)}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
getFrontendUrl(instanceOrigin) {
|
|
98
|
-
try {
|
|
99
|
-
const url = new URL(instanceOrigin);
|
|
100
|
-
if (url.hostname === 'localhost' || url.hostname === '127.0.0.1') {
|
|
101
|
-
url.port = '4200';
|
|
102
|
-
return url.origin;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
// fall through
|
|
107
|
-
}
|
|
108
|
-
return instanceOrigin;
|
|
109
|
-
}
|
|
110
|
-
}
|