@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.
Files changed (75) hide show
  1. package/README.md +17 -9
  2. package/dist/base-command.d.ts +24 -0
  3. package/dist/base-command.js +37 -0
  4. package/dist/commands/auth/index.js +1 -1
  5. package/dist/commands/profile/me/index.js +21 -2
  6. package/dist/commands/profile/wizard/index.js +1 -1
  7. package/dist/commands/profile/workspace/set/index.js +1 -1
  8. package/dist/commands/{ephemeral → sandbox}/env/delete/index.d.ts +1 -4
  9. package/dist/commands/{ephemeral → sandbox}/env/delete/index.js +17 -33
  10. package/dist/commands/{ephemeral → sandbox}/env/get/index.d.ts +1 -4
  11. package/dist/commands/{ephemeral → sandbox}/env/get/index.js +13 -29
  12. package/dist/commands/{ephemeral → sandbox}/env/get_all/index.d.ts +1 -4
  13. package/dist/commands/{ephemeral → sandbox}/env/get_all/index.js +16 -32
  14. package/dist/commands/{ephemeral → sandbox}/env/list/index.d.ts +1 -4
  15. package/dist/commands/sandbox/env/list/index.js +67 -0
  16. package/dist/commands/{ephemeral → sandbox}/env/set/index.d.ts +1 -4
  17. package/dist/commands/{ephemeral → sandbox}/env/set/index.js +14 -30
  18. package/dist/commands/{ephemeral → sandbox}/env/set_all/index.d.ts +1 -4
  19. package/dist/commands/{ephemeral → sandbox}/env/set_all/index.js +16 -32
  20. package/dist/commands/{ephemeral → sandbox}/get/index.d.ts +1 -4
  21. package/dist/commands/sandbox/get/index.js +48 -0
  22. package/dist/commands/sandbox/impersonate/index.d.ts +5 -0
  23. package/dist/commands/sandbox/impersonate/index.js +5 -0
  24. package/dist/commands/{ephemeral → sandbox}/license/get/index.d.ts +1 -4
  25. package/dist/commands/{ephemeral → sandbox}/license/get/index.js +16 -32
  26. package/dist/commands/{ephemeral → sandbox}/license/set/index.d.ts +1 -4
  27. package/dist/commands/{ephemeral → sandbox}/license/set/index.js +17 -33
  28. package/dist/commands/{ephemeral → sandbox}/pull/index.d.ts +1 -2
  29. package/dist/commands/{ephemeral → sandbox}/pull/index.js +11 -26
  30. package/dist/commands/{ephemeral → sandbox}/push/index.d.ts +1 -2
  31. package/dist/commands/{ephemeral → sandbox}/push/index.js +13 -28
  32. package/dist/commands/{ephemeral/delete → sandbox/reset}/index.d.ts +1 -5
  33. package/dist/commands/sandbox/reset/index.js +71 -0
  34. package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.d.ts +1 -4
  35. package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.js +15 -31
  36. package/dist/commands/{ephemeral/unit_test/run_all → sandbox/unit_test/list}/index.d.ts +1 -2
  37. package/dist/commands/{ephemeral → sandbox}/unit_test/list/index.js +10 -24
  38. package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.d.ts +1 -2
  39. package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.js +9 -23
  40. package/dist/commands/{ephemeral/unit_test/list → sandbox/unit_test/run_all}/index.d.ts +1 -2
  41. package/dist/commands/{ephemeral → sandbox}/unit_test/run_all/index.js +9 -23
  42. package/dist/commands/{ephemeral/workflow_test/get → sandbox/workflow_test/delete}/index.d.ts +1 -2
  43. package/dist/commands/{ephemeral → sandbox}/workflow_test/delete/index.js +9 -23
  44. package/dist/commands/{ephemeral/workflow_test/run → sandbox/workflow_test/get}/index.d.ts +1 -2
  45. package/dist/commands/{ephemeral → sandbox}/workflow_test/get/index.js +8 -25
  46. package/dist/commands/{ephemeral/workflow_test/run_all → sandbox/workflow_test/list}/index.d.ts +1 -2
  47. package/dist/commands/{ephemeral → sandbox}/workflow_test/list/index.js +11 -25
  48. package/dist/commands/{ephemeral/workflow_test/delete → sandbox/workflow_test/run}/index.d.ts +1 -2
  49. package/dist/commands/{ephemeral → sandbox}/workflow_test/run/index.js +9 -23
  50. package/dist/commands/{ephemeral/workflow_test/list → sandbox/workflow_test/run_all}/index.d.ts +1 -2
  51. package/dist/commands/{ephemeral → sandbox}/workflow_test/run_all/index.js +9 -23
  52. package/dist/commands/tenant/create/index.d.ts +2 -1
  53. package/dist/commands/tenant/create/index.js +23 -6
  54. package/dist/commands/tenant/get/index.js +2 -2
  55. package/dist/commands/tenant/list/index.js +2 -2
  56. package/dist/commands/tenant/push/index.js +0 -34
  57. package/dist/commands/workspace/edit/index.d.ts +1 -0
  58. package/dist/commands/workspace/edit/index.js +16 -6
  59. package/dist/commands/workspace/get/index.js +9 -7
  60. package/dist/commands/workspace/list/index.d.ts +1 -0
  61. package/dist/commands/workspace/list/index.js +14 -7
  62. package/dist/commands/workspace/push/index.js +26 -0
  63. package/oclif.manifest.json +1788 -2249
  64. package/package.json +7 -7
  65. package/dist/commands/ephemeral/access/index.d.ts +0 -15
  66. package/dist/commands/ephemeral/access/index.js +0 -78
  67. package/dist/commands/ephemeral/create/index.d.ts +0 -17
  68. package/dist/commands/ephemeral/create/index.js +0 -102
  69. package/dist/commands/ephemeral/delete/index.js +0 -99
  70. package/dist/commands/ephemeral/env/list/index.js +0 -83
  71. package/dist/commands/ephemeral/get/index.js +0 -102
  72. package/dist/commands/ephemeral/list/index.d.ts +0 -15
  73. package/dist/commands/ephemeral/list/index.js +0 -109
  74. package/dist/commands/ephemeral/shared/index.d.ts +0 -15
  75. package/dist/commands/ephemeral/shared/index.js +0 -108
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xano/cli",
3
3
  "description": "CLI for Xano's Metadata API",
4
- "version": "0.0.95-beta.2",
4
+ "version": "0.0.95-beta.5",
5
5
  "author": "Sean Montgomery",
6
6
  "bin": {
7
7
  "xano": "./bin/run.js"
@@ -66,14 +66,14 @@
66
66
  "branch": {
67
67
  "description": "Manage workspace branches"
68
68
  },
69
- "ephemeral": {
70
- "description": "Manage ephemeral tenants"
69
+ "sandbox": {
70
+ "description": "Manage your sandbox environment"
71
71
  },
72
- "ephemeral:unit_test": {
73
- "description": "Manage and run unit tests for ephemeral tenants"
72
+ "sandbox:unit_test": {
73
+ "description": "Manage and run unit tests for your sandbox environment"
74
74
  },
75
- "ephemeral:workflow_test": {
76
- "description": "Manage and run workflow tests for ephemeral tenants"
75
+ "sandbox:workflow_test": {
76
+ "description": "Manage and run workflow tests for your sandbox environment"
77
77
  },
78
78
  "function": {
79
79
  "description": "Manage reusable functions in a workspace"
@@ -1,15 +0,0 @@
1
- import BaseCommand from '../../../base-command.js';
2
- export default class EphemeralAccess extends BaseCommand {
3
- static args: {
4
- tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
- access: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
- };
7
- static description: string;
8
- static examples: string[];
9
- static flags: {
10
- output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
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
- }
@@ -1,78 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import BaseCommand from '../../../base-command.js';
3
- export default class EphemeralAccess extends BaseCommand {
4
- static args = {
5
- tenant_name: Args.string({
6
- description: 'Ephemeral tenant name',
7
- required: true,
8
- }),
9
- access: Args.string({
10
- description: 'Access level to set',
11
- options: ['private', 'shared'],
12
- required: true,
13
- }),
14
- };
15
- static description = 'Change the access level of an ephemeral tenant';
16
- static examples = [
17
- `$ xano ephemeral access e1a2-b3c4-x5y6 shared
18
- Access updated to shared for tenant e1a2-b3c4-x5y6
19
- `,
20
- `$ xano ephemeral access e1a2-b3c4-x5y6 private`,
21
- ];
22
- static flags = {
23
- ...BaseCommand.baseFlags,
24
- output: Flags.string({
25
- char: 'o',
26
- default: 'summary',
27
- description: 'Output format',
28
- options: ['summary', 'json'],
29
- required: false,
30
- }),
31
- };
32
- async run() {
33
- const { args, flags } = await this.parse(EphemeralAccess);
34
- const profileName = flags.profile || this.getDefaultProfile();
35
- const credentials = this.loadCredentialsFile();
36
- if (!credentials || !(profileName in credentials.profiles)) {
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 apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(args.tenant_name)}/access`;
47
- try {
48
- const response = await this.verboseFetch(apiUrl, {
49
- body: JSON.stringify({ access: args.access }),
50
- headers: {
51
- accept: 'application/json',
52
- Authorization: `Bearer ${profile.access_token}`,
53
- 'Content-Type': 'application/json',
54
- },
55
- method: 'PATCH',
56
- }, flags.verbose, profile.access_token);
57
- if (!response.ok) {
58
- const errorText = await response.text();
59
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
60
- }
61
- const tenant = await response.json();
62
- if (flags.output === 'json') {
63
- this.log(JSON.stringify(tenant, null, 2));
64
- }
65
- else {
66
- this.log(`Access updated to ${args.access} for tenant ${args.tenant_name}`);
67
- }
68
- }
69
- catch (error) {
70
- if (error instanceof Error) {
71
- this.error(`Failed to update access: ${error.message}`);
72
- }
73
- else {
74
- this.error(`Failed to update access: ${String(error)}`);
75
- }
76
- }
77
- }
78
- }
@@ -1,17 +0,0 @@
1
- import BaseCommand from '../../../base-command.js';
2
- export default class EphemeralCreate extends BaseCommand {
3
- static args: {
4
- display: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- access: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
- description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- domain: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
- output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
- verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- };
16
- run(): Promise<void>;
17
- }
@@ -1,102 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import BaseCommand from '../../../base-command.js';
3
- export default class EphemeralCreate extends BaseCommand {
4
- static args = {
5
- display: Args.string({
6
- description: 'Optional display name for the ephemeral tenant',
7
- required: false,
8
- }),
9
- };
10
- static description = 'Create an ephemeral tenant (workspace-agnostic, no background tasks)';
11
- static examples = [
12
- `$ xano ephemeral create
13
- Created ephemeral tenant: e1a2-b3c4-x5y6 - ID: 42
14
- `,
15
- `$ xano ephemeral create "My Ephemeral"`,
16
- `$ xano ephemeral create "CI Tenant" -d "For CI/CD" -o json`,
17
- ];
18
- static flags = {
19
- ...BaseCommand.baseFlags,
20
- access: Flags.string({
21
- char: 'a',
22
- default: 'private',
23
- description: 'Access level (private or shared)',
24
- options: ['private', 'shared'],
25
- required: false,
26
- }),
27
- description: Flags.string({
28
- char: 'd',
29
- description: 'Tenant description',
30
- required: false,
31
- }),
32
- domain: Flags.string({
33
- description: 'Custom domain for the tenant',
34
- required: false,
35
- }),
36
- output: Flags.string({
37
- char: 'o',
38
- default: 'summary',
39
- description: 'Output format',
40
- options: ['summary', 'json'],
41
- required: false,
42
- }),
43
- };
44
- async run() {
45
- const { args, flags } = await this.parse(EphemeralCreate);
46
- const profileName = flags.profile || this.getDefaultProfile();
47
- const credentials = this.loadCredentialsFile();
48
- if (!credentials || !(profileName in credentials.profiles)) {
49
- this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
50
- }
51
- const profile = credentials.profiles[profileName];
52
- if (!profile.instance_origin) {
53
- this.error(`Profile '${profileName}' is missing instance_origin`);
54
- }
55
- if (!profile.access_token) {
56
- this.error(`Profile '${profileName}' is missing access_token`);
57
- }
58
- const body = {
59
- access: flags.access,
60
- display: args.display || '',
61
- tag: [],
62
- };
63
- if (flags.description)
64
- body.description = flags.description;
65
- if (flags.domain)
66
- body.domain = flags.domain;
67
- const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant`;
68
- try {
69
- const response = await this.verboseFetch(apiUrl, {
70
- body: JSON.stringify(body),
71
- headers: {
72
- accept: 'application/json',
73
- Authorization: `Bearer ${profile.access_token}`,
74
- 'Content-Type': 'application/json',
75
- },
76
- method: 'POST',
77
- }, flags.verbose, profile.access_token);
78
- if (!response.ok) {
79
- const errorText = await response.text();
80
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
81
- }
82
- const tenant = (await response.json());
83
- if (flags.output === 'json') {
84
- this.log(JSON.stringify(tenant, null, 2));
85
- }
86
- else {
87
- this.log(`Created ephemeral tenant: ${tenant.display || tenant.name} (${tenant.name}) - ID: ${tenant.id}`);
88
- if (tenant.state) {
89
- this.log(` State: ${tenant.state}`);
90
- }
91
- }
92
- }
93
- catch (error) {
94
- if (error instanceof Error) {
95
- this.error(`Failed to create ephemeral tenant: ${error.message}`);
96
- }
97
- else {
98
- this.error(`Failed to create ephemeral tenant: ${String(error)}`);
99
- }
100
- }
101
- }
102
- }
@@ -1,99 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import BaseCommand from '../../../base-command.js';
3
- export default class EphemeralDelete extends BaseCommand {
4
- static args = {
5
- tenant_name: Args.string({
6
- description: 'Ephemeral tenant name to delete',
7
- required: true,
8
- }),
9
- };
10
- static description = 'Delete an ephemeral tenant permanently. This cannot be undone.';
11
- static examples = [
12
- `$ xano ephemeral delete my-tenant
13
- Are you sure you want to delete ephemeral tenant my-tenant? This action cannot be undone. (y/N) y
14
- Deleted ephemeral tenant my-tenant
15
- `,
16
- `$ xano ephemeral delete my-tenant --force`,
17
- `$ xano ephemeral delete my-tenant -f -o json`,
18
- ];
19
- static flags = {
20
- ...BaseCommand.baseFlags,
21
- force: Flags.boolean({
22
- char: 'f',
23
- default: false,
24
- description: 'Skip confirmation prompt',
25
- required: false,
26
- }),
27
- output: Flags.string({
28
- char: 'o',
29
- default: 'summary',
30
- description: 'Output format',
31
- options: ['summary', 'json'],
32
- required: false,
33
- }),
34
- };
35
- async run() {
36
- const { args, flags } = await this.parse(EphemeralDelete);
37
- const profileName = flags.profile || this.getDefaultProfile();
38
- const credentials = this.loadCredentialsFile();
39
- if (!credentials || !(profileName in credentials.profiles)) {
40
- this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
41
- }
42
- const profile = credentials.profiles[profileName];
43
- if (!profile.instance_origin) {
44
- this.error(`Profile '${profileName}' is missing instance_origin`);
45
- }
46
- if (!profile.access_token) {
47
- this.error(`Profile '${profileName}' is missing access_token`);
48
- }
49
- const tenantName = args.tenant_name;
50
- if (!flags.force) {
51
- const confirmed = await this.confirm(`Are you sure you want to delete ephemeral tenant ${tenantName}? This action cannot be undone.`);
52
- if (!confirmed) {
53
- this.log('Deletion cancelled.');
54
- return;
55
- }
56
- }
57
- const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(tenantName)}`;
58
- try {
59
- const response = await this.verboseFetch(apiUrl, {
60
- headers: {
61
- accept: 'application/json',
62
- Authorization: `Bearer ${profile.access_token}`,
63
- },
64
- method: 'DELETE',
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
- if (flags.output === 'json') {
71
- this.log(JSON.stringify({ deleted: true, tenant_name: tenantName }, null, 2));
72
- }
73
- else {
74
- this.log(`Deleted ephemeral tenant ${tenantName}`);
75
- }
76
- }
77
- catch (error) {
78
- if (error instanceof Error) {
79
- this.error(`Failed to delete ephemeral tenant: ${error.message}`);
80
- }
81
- else {
82
- this.error(`Failed to delete ephemeral tenant: ${String(error)}`);
83
- }
84
- }
85
- }
86
- async confirm(message) {
87
- const readline = await import('node:readline');
88
- const rl = readline.createInterface({
89
- input: process.stdin,
90
- output: process.stdout,
91
- });
92
- return new Promise((resolve) => {
93
- rl.question(`${message} (y/N) `, (answer) => {
94
- rl.close();
95
- resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
96
- });
97
- });
98
- }
99
- }
@@ -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,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,15 +0,0 @@
1
- import BaseCommand from '../../../base-command.js';
2
- export default class EphemeralList extends BaseCommand {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- order: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
- output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
- page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
- per_page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
- sort: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
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
- }
@@ -1,109 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import BaseCommand from '../../../base-command.js';
3
- export default class EphemeralList extends BaseCommand {
4
- static description = 'List ephemeral tenants';
5
- static examples = [
6
- `$ xano ephemeral list
7
- Ephemeral tenants:
8
- - My Tenant (my-tenant) [ok]
9
- - CI Tenant (ci-tenant) [ok]
10
- `,
11
- `$ xano ephemeral list -o json`,
12
- ];
13
- static flags = {
14
- ...BaseCommand.baseFlags,
15
- order: Flags.string({
16
- default: 'asc',
17
- description: 'Sort order',
18
- options: ['asc', 'desc'],
19
- required: false,
20
- }),
21
- output: Flags.string({
22
- char: 'o',
23
- default: 'summary',
24
- description: 'Output format',
25
- options: ['summary', 'json'],
26
- required: false,
27
- }),
28
- page: Flags.integer({
29
- default: 1,
30
- description: 'Page number',
31
- required: false,
32
- }),
33
- per_page: Flags.integer({
34
- default: 50,
35
- description: 'Items per page',
36
- required: false,
37
- }),
38
- sort: Flags.string({
39
- default: 'name',
40
- description: 'Sort field',
41
- options: ['name', 'created_at', 'state'],
42
- required: false,
43
- }),
44
- };
45
- async run() {
46
- const { flags } = await this.parse(EphemeralList);
47
- const profileName = flags.profile || this.getDefaultProfile();
48
- const credentials = this.loadCredentialsFile();
49
- if (!credentials || !(profileName in credentials.profiles)) {
50
- this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
51
- }
52
- const profile = credentials.profiles[profileName];
53
- if (!profile.instance_origin) {
54
- this.error(`Profile '${profileName}' is missing instance_origin`);
55
- }
56
- if (!profile.access_token) {
57
- this.error(`Profile '${profileName}' is missing access_token`);
58
- }
59
- const params = new URLSearchParams({
60
- order: flags.order,
61
- page: String(flags.page),
62
- per_page: String(flags.per_page),
63
- sort: flags.sort,
64
- });
65
- const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant?${params}`;
66
- try {
67
- const response = await this.verboseFetch(apiUrl, {
68
- headers: {
69
- accept: 'application/json',
70
- Authorization: `Bearer ${profile.access_token}`,
71
- },
72
- method: 'GET',
73
- }, flags.verbose, profile.access_token);
74
- if (!response.ok) {
75
- const errorText = await response.text();
76
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
77
- }
78
- const data = (await response.json());
79
- const tenants = data.items ?? [];
80
- if (flags.output === 'json') {
81
- this.log(JSON.stringify(data, null, 2));
82
- }
83
- else {
84
- if (tenants.length === 0) {
85
- this.log('No ephemeral tenants found');
86
- }
87
- else {
88
- this.log('Ephemeral tenants:');
89
- for (const tenant of tenants) {
90
- const state = tenant.state ? ` [${tenant.state}]` : '';
91
- const access = tenant.ephemeral_access ? ` [${tenant.ephemeral_access}]` : '';
92
- this.log(` - ${tenant.display || tenant.name} (${tenant.name})${state}${access}`);
93
- }
94
- if (data.nextPage) {
95
- this.log(`\nPage ${data.curPage} — more results available (use --page ${data.nextPage})`);
96
- }
97
- }
98
- }
99
- }
100
- catch (error) {
101
- if (error instanceof Error) {
102
- this.error(`Failed to list ephemeral tenants: ${error.message}`);
103
- }
104
- else {
105
- this.error(`Failed to list ephemeral tenants: ${String(error)}`);
106
- }
107
- }
108
- }
109
- }
@@ -1,15 +0,0 @@
1
- import BaseCommand from '../../../base-command.js';
2
- export default class EphemeralShared extends BaseCommand {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- order: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
- output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
- page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
- per_page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
- sort: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
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
- }