@xano/cli 0.0.37 → 0.0.40

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 (114) hide show
  1. package/README.md +325 -102
  2. package/dist/commands/auth/index.d.ts +0 -2
  3. package/dist/commands/auth/index.js +2 -55
  4. package/dist/commands/profile/create/index.d.ts +0 -2
  5. package/dist/commands/profile/create/index.js +0 -15
  6. package/dist/commands/profile/edit/index.d.ts +0 -4
  7. package/dist/commands/profile/edit/index.js +7 -38
  8. package/dist/commands/profile/wizard/index.d.ts +0 -2
  9. package/dist/commands/profile/wizard/index.js +0 -106
  10. package/dist/commands/profile/{project → workspace}/index.d.ts +1 -1
  11. package/dist/commands/profile/{project → workspace}/index.js +10 -10
  12. package/dist/commands/release/delete/index.d.ts +2 -4
  13. package/dist/commands/release/delete/index.js +39 -12
  14. package/dist/commands/release/edit/index.d.ts +2 -4
  15. package/dist/commands/release/edit/index.js +31 -5
  16. package/dist/commands/release/export/index.d.ts +2 -4
  17. package/dist/commands/release/export/index.js +39 -11
  18. package/dist/commands/release/get/index.d.ts +2 -4
  19. package/dist/commands/release/get/index.js +31 -5
  20. package/dist/commands/release/pull/index.d.ts +31 -0
  21. package/dist/commands/release/pull/index.js +345 -0
  22. package/dist/commands/release/push/index.d.ts +26 -0
  23. package/dist/commands/release/push/index.js +230 -0
  24. package/dist/commands/tenant/backup/delete/index.d.ts +1 -1
  25. package/dist/commands/tenant/backup/delete/index.js +8 -9
  26. package/dist/commands/tenant/backup/export/index.d.ts +1 -1
  27. package/dist/commands/tenant/backup/export/index.js +9 -10
  28. package/dist/commands/tenant/backup/restore/index.d.ts +1 -1
  29. package/dist/commands/tenant/backup/restore/index.js +8 -9
  30. package/dist/commands/tenant/cluster/create/index.d.ts +18 -0
  31. package/dist/commands/tenant/cluster/create/index.js +149 -0
  32. package/dist/commands/{run/sessions/start → tenant/cluster/delete}/index.d.ts +9 -3
  33. package/dist/commands/tenant/cluster/delete/index.js +125 -0
  34. package/dist/commands/tenant/cluster/edit/index.d.ts +22 -0
  35. package/dist/commands/tenant/cluster/edit/index.js +128 -0
  36. package/dist/commands/{run/sessions → tenant/cluster}/get/index.d.ts +7 -3
  37. package/dist/commands/tenant/cluster/get/index.js +114 -0
  38. package/dist/commands/{run/info → tenant/cluster/license/get}/index.d.ts +10 -7
  39. package/dist/commands/tenant/cluster/license/get/index.js +118 -0
  40. package/dist/commands/tenant/cluster/license/set/index.d.ts +21 -0
  41. package/dist/commands/tenant/cluster/license/set/index.js +132 -0
  42. package/dist/commands/{run/env → tenant/cluster}/list/index.d.ts +3 -3
  43. package/dist/commands/tenant/cluster/list/index.js +109 -0
  44. package/dist/commands/tenant/create/index.d.ts +6 -3
  45. package/dist/commands/tenant/create/index.js +28 -20
  46. package/dist/commands/tenant/deploy_platform/index.d.ts +1 -1
  47. package/dist/commands/tenant/deploy_platform/index.js +8 -9
  48. package/dist/commands/tenant/deploy_release/index.d.ts +1 -1
  49. package/dist/commands/tenant/deploy_release/index.js +13 -13
  50. package/dist/commands/tenant/env/delete/index.d.ts +19 -0
  51. package/dist/commands/tenant/env/delete/index.js +139 -0
  52. package/dist/commands/{run/projects/create → tenant/env/get}/index.d.ts +7 -4
  53. package/dist/commands/tenant/env/get/index.js +113 -0
  54. package/dist/commands/{run/projects/update → tenant/env/get_all}/index.d.ts +7 -5
  55. package/dist/commands/tenant/env/get_all/index.js +123 -0
  56. package/dist/commands/{run/secrets/get → tenant/env/list}/index.d.ts +5 -3
  57. package/dist/commands/tenant/env/list/index.js +116 -0
  58. package/dist/commands/tenant/env/set/index.d.ts +18 -0
  59. package/dist/commands/tenant/env/set/index.js +122 -0
  60. package/dist/commands/tenant/env/set_all/index.d.ts +18 -0
  61. package/dist/commands/tenant/env/set_all/index.js +131 -0
  62. package/dist/commands/tenant/get/index.js +6 -5
  63. package/dist/commands/tenant/impersonate/index.d.ts +19 -0
  64. package/dist/commands/tenant/impersonate/index.js +146 -0
  65. package/dist/commands/tenant/license/get/index.d.ts +18 -0
  66. package/dist/commands/tenant/license/get/index.js +127 -0
  67. package/dist/commands/tenant/license/set/index.d.ts +19 -0
  68. package/dist/commands/tenant/license/set/index.js +141 -0
  69. package/dist/commands/tenant/list/index.js +6 -6
  70. package/dist/commands/tenant/pull/index.d.ts +31 -0
  71. package/dist/commands/tenant/pull/index.js +327 -0
  72. package/dist/commands/tenant/push/index.d.ts +24 -0
  73. package/dist/commands/tenant/push/index.js +245 -0
  74. package/oclif.manifest.json +2076 -1670
  75. package/package.json +1 -19
  76. package/dist/commands/run/env/delete/index.d.ts +0 -14
  77. package/dist/commands/run/env/delete/index.js +0 -65
  78. package/dist/commands/run/env/get/index.d.ts +0 -14
  79. package/dist/commands/run/env/get/index.js +0 -52
  80. package/dist/commands/run/env/list/index.js +0 -56
  81. package/dist/commands/run/env/set/index.d.ts +0 -14
  82. package/dist/commands/run/env/set/index.js +0 -51
  83. package/dist/commands/run/exec/index.d.ts +0 -31
  84. package/dist/commands/run/exec/index.js +0 -431
  85. package/dist/commands/run/info/index.js +0 -160
  86. package/dist/commands/run/projects/create/index.js +0 -75
  87. package/dist/commands/run/projects/delete/index.d.ts +0 -14
  88. package/dist/commands/run/projects/delete/index.js +0 -65
  89. package/dist/commands/run/projects/list/index.d.ts +0 -13
  90. package/dist/commands/run/projects/list/index.js +0 -66
  91. package/dist/commands/run/projects/update/index.js +0 -86
  92. package/dist/commands/run/secrets/delete/index.d.ts +0 -14
  93. package/dist/commands/run/secrets/delete/index.js +0 -65
  94. package/dist/commands/run/secrets/get/index.js +0 -52
  95. package/dist/commands/run/secrets/list/index.d.ts +0 -12
  96. package/dist/commands/run/secrets/list/index.js +0 -60
  97. package/dist/commands/run/secrets/set/index.d.ts +0 -16
  98. package/dist/commands/run/secrets/set/index.js +0 -74
  99. package/dist/commands/run/sessions/delete/index.d.ts +0 -14
  100. package/dist/commands/run/sessions/delete/index.js +0 -65
  101. package/dist/commands/run/sessions/get/index.js +0 -72
  102. package/dist/commands/run/sessions/list/index.d.ts +0 -13
  103. package/dist/commands/run/sessions/list/index.js +0 -64
  104. package/dist/commands/run/sessions/start/index.js +0 -56
  105. package/dist/commands/run/sessions/stop/index.d.ts +0 -14
  106. package/dist/commands/run/sessions/stop/index.js +0 -56
  107. package/dist/commands/run/sink/get/index.d.ts +0 -14
  108. package/dist/commands/run/sink/get/index.js +0 -63
  109. package/dist/lib/base-run-command.d.ts +0 -41
  110. package/dist/lib/base-run-command.js +0 -75
  111. package/dist/lib/run-http-client.d.ts +0 -64
  112. package/dist/lib/run-http-client.js +0 -171
  113. package/dist/lib/run-types.d.ts +0 -226
  114. package/dist/lib/run-types.js +0 -5
@@ -0,0 +1,132 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import * as yaml from 'js-yaml';
3
+ import * as fs from 'node:fs';
4
+ import * as os from 'node:os';
5
+ import * as path from 'node:path';
6
+ import BaseCommand from '../../../../../base-command.js';
7
+ export default class TenantClusterLicenseSet extends BaseCommand {
8
+ static args = {
9
+ cluster_id: Args.integer({
10
+ description: 'Tenant cluster ID',
11
+ required: true,
12
+ }),
13
+ };
14
+ static description = 'Set/update the license (kubeconfig) for a tenant cluster';
15
+ static examples = [
16
+ `$ xano tenant cluster license set 1
17
+ Reads from kubeconfig-1.yaml
18
+ `,
19
+ `$ xano tenant cluster license set 1 --file ./kubeconfig.yaml`,
20
+ `$ xano tenant cluster license set 1 --value 'apiVersion: v1...'`,
21
+ `$ xano tenant cluster license set 1 -o json`,
22
+ ];
23
+ static flags = {
24
+ ...BaseCommand.baseFlags,
25
+ clean: Flags.boolean({
26
+ default: false,
27
+ description: 'Remove the source file after successful upload',
28
+ exclusive: ['value'],
29
+ required: false,
30
+ }),
31
+ file: Flags.string({
32
+ char: 'f',
33
+ description: 'Path to kubeconfig file (default: kubeconfig_<cluster_id>.yaml)',
34
+ exclusive: ['value'],
35
+ required: false,
36
+ }),
37
+ output: Flags.string({
38
+ char: 'o',
39
+ default: 'summary',
40
+ description: 'Output format',
41
+ options: ['summary', 'json'],
42
+ required: false,
43
+ }),
44
+ value: Flags.string({
45
+ description: 'Inline kubeconfig YAML value',
46
+ exclusive: ['file', 'clean'],
47
+ required: false,
48
+ }),
49
+ };
50
+ async run() {
51
+ const { args, flags } = await this.parse(TenantClusterLicenseSet);
52
+ const clusterId = args.cluster_id;
53
+ let licenseValue;
54
+ let sourceFilePath;
55
+ if (flags.value) {
56
+ licenseValue = flags.value;
57
+ }
58
+ else {
59
+ sourceFilePath = path.resolve(flags.file || `kubeconfig_${clusterId}.yaml`);
60
+ if (!fs.existsSync(sourceFilePath)) {
61
+ this.error(`File not found: ${sourceFilePath}`);
62
+ }
63
+ licenseValue = fs.readFileSync(sourceFilePath, 'utf8');
64
+ }
65
+ const profileName = flags.profile || this.getDefaultProfile();
66
+ const credentials = this.loadCredentials();
67
+ if (!(profileName in credentials.profiles)) {
68
+ this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
69
+ `Create a profile using 'xano profile create'`);
70
+ }
71
+ const profile = credentials.profiles[profileName];
72
+ if (!profile.instance_origin) {
73
+ this.error(`Profile '${profileName}' is missing instance_origin`);
74
+ }
75
+ if (!profile.access_token) {
76
+ this.error(`Profile '${profileName}' is missing access_token`);
77
+ }
78
+ const apiUrl = `${profile.instance_origin}/api:meta/tenant/cluster/${clusterId}/license`;
79
+ try {
80
+ const response = await this.verboseFetch(apiUrl, {
81
+ body: JSON.stringify({ value: licenseValue }),
82
+ headers: {
83
+ accept: 'application/json',
84
+ Authorization: `Bearer ${profile.access_token}`,
85
+ 'Content-Type': 'application/json',
86
+ },
87
+ method: 'POST',
88
+ }, flags.verbose, profile.access_token);
89
+ if (!response.ok) {
90
+ const errorText = await response.text();
91
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
92
+ }
93
+ const result = await response.json();
94
+ if (flags.output === 'json') {
95
+ this.log(JSON.stringify(result, null, 2));
96
+ }
97
+ else {
98
+ this.log(`Tenant cluster license updated successfully for cluster ${clusterId}`);
99
+ }
100
+ if (flags.clean && sourceFilePath && fs.existsSync(sourceFilePath)) {
101
+ fs.unlinkSync(sourceFilePath);
102
+ this.log(`Removed ${sourceFilePath}`);
103
+ }
104
+ }
105
+ catch (error) {
106
+ if (error instanceof Error) {
107
+ this.error(`Failed to set tenant cluster license: ${error.message}`);
108
+ }
109
+ else {
110
+ this.error(`Failed to set tenant cluster license: ${String(error)}`);
111
+ }
112
+ }
113
+ }
114
+ loadCredentials() {
115
+ const configDir = path.join(os.homedir(), '.xano');
116
+ const credentialsPath = path.join(configDir, 'credentials.yaml');
117
+ if (!fs.existsSync(credentialsPath)) {
118
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
119
+ }
120
+ try {
121
+ const fileContent = fs.readFileSync(credentialsPath, 'utf8');
122
+ const parsed = yaml.load(fileContent);
123
+ if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
124
+ this.error('Credentials file has invalid format.');
125
+ }
126
+ return parsed;
127
+ }
128
+ catch (error) {
129
+ this.error(`Failed to parse credentials file: ${error}`);
130
+ }
131
+ }
132
+ }
@@ -1,6 +1,5 @@
1
- import BaseRunCommand from '../../../../lib/base-run-command.js';
2
- export default class RunEnvList extends BaseRunCommand {
3
- static args: {};
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class TenantClusterList extends BaseCommand {
4
3
  static description: string;
5
4
  static examples: string[];
6
5
  static flags: {
@@ -9,4 +8,5 @@ export default class RunEnvList extends BaseRunCommand {
9
8
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
9
  };
11
10
  run(): Promise<void>;
11
+ private loadCredentials;
12
12
  }
@@ -0,0 +1,109 @@
1
+ import { Flags } from '@oclif/core';
2
+ import * as yaml from 'js-yaml';
3
+ import * as fs from 'node:fs';
4
+ import * as os from 'node:os';
5
+ import * as path from 'node:path';
6
+ import BaseCommand from '../../../../base-command.js';
7
+ export default class TenantClusterList extends BaseCommand {
8
+ static description = 'List all tenant clusters';
9
+ static examples = [
10
+ `$ xano tenant cluster list
11
+ Tenant clusters:
12
+ - us-east-1 (standard) [ID: 1]
13
+ - eu-west-1 (run) [ID: 2]
14
+ `,
15
+ `$ xano tenant cluster list --output json`,
16
+ ];
17
+ static flags = {
18
+ ...BaseCommand.baseFlags,
19
+ output: Flags.string({
20
+ char: 'o',
21
+ default: 'summary',
22
+ description: 'Output format',
23
+ options: ['summary', 'json'],
24
+ required: false,
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(TenantClusterList);
29
+ const profileName = flags.profile || this.getDefaultProfile();
30
+ const credentials = this.loadCredentials();
31
+ if (!(profileName in credentials.profiles)) {
32
+ this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
33
+ `Create a profile using 'xano profile create'`);
34
+ }
35
+ const profile = credentials.profiles[profileName];
36
+ if (!profile.instance_origin) {
37
+ this.error(`Profile '${profileName}' is missing instance_origin`);
38
+ }
39
+ if (!profile.access_token) {
40
+ this.error(`Profile '${profileName}' is missing access_token`);
41
+ }
42
+ const apiUrl = `${profile.instance_origin}/api:meta/tenant/cluster`;
43
+ try {
44
+ const response = await this.verboseFetch(apiUrl, {
45
+ headers: {
46
+ accept: 'application/json',
47
+ Authorization: `Bearer ${profile.access_token}`,
48
+ },
49
+ method: 'GET',
50
+ }, flags.verbose, profile.access_token);
51
+ if (!response.ok) {
52
+ const errorText = await response.text();
53
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
54
+ }
55
+ const data = (await response.json());
56
+ let clusters;
57
+ if (Array.isArray(data)) {
58
+ clusters = data;
59
+ }
60
+ else if (data && typeof data === 'object' && 'items' in data && Array.isArray(data.items)) {
61
+ clusters = data.items;
62
+ }
63
+ else {
64
+ this.error('Unexpected API response format');
65
+ }
66
+ if (flags.output === 'json') {
67
+ this.log(JSON.stringify(clusters, null, 2));
68
+ }
69
+ else {
70
+ if (clusters.length === 0) {
71
+ this.log('No tenant clusters found');
72
+ }
73
+ else {
74
+ this.log('Tenant clusters:');
75
+ for (const cluster of clusters) {
76
+ const type = cluster.type ? ` (${cluster.type})` : '';
77
+ this.log(` - ${cluster.name}${type} [ID: ${cluster.id}]`);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ catch (error) {
83
+ if (error instanceof Error) {
84
+ this.error(`Failed to list tenant clusters: ${error.message}`);
85
+ }
86
+ else {
87
+ this.error(`Failed to list tenant clusters: ${String(error)}`);
88
+ }
89
+ }
90
+ }
91
+ loadCredentials() {
92
+ const configDir = path.join(os.homedir(), '.xano');
93
+ const credentialsPath = path.join(configDir, 'credentials.yaml');
94
+ if (!fs.existsSync(credentialsPath)) {
95
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
96
+ }
97
+ try {
98
+ const fileContent = fs.readFileSync(credentialsPath, 'utf8');
99
+ const parsed = yaml.load(fileContent);
100
+ if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
101
+ this.error('Credentials file has invalid format.');
102
+ }
103
+ return parsed;
104
+ }
105
+ catch (error) {
106
+ this.error(`Failed to parse credentials file: ${error}`);
107
+ }
108
+ }
109
+ }
@@ -1,16 +1,19 @@
1
1
  import BaseCommand from '../../../base-command.js';
2
2
  export default class TenantCreate extends BaseCommand {
3
+ static args: {
4
+ display: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
3
6
  static description: string;
4
7
  static examples: string[];
5
8
  static flags: {
6
- 'cluster-id': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ cluster_id: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
10
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- display: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
11
  domain: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ ephemeral: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
13
  ingress: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
14
  license: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
15
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- 'platform-id': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ platform_id: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
17
  tasks: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
18
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
19
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -1,20 +1,26 @@
1
- import { Flags } from '@oclif/core';
1
+ import { Args, Flags } from '@oclif/core';
2
2
  import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
4
  import * as os from 'node:os';
5
5
  import * as path from 'node:path';
6
6
  import BaseCommand from '../../../base-command.js';
7
7
  export default class TenantCreate extends BaseCommand {
8
+ static args = {
9
+ display: Args.string({
10
+ description: 'Display name for the tenant',
11
+ required: true,
12
+ }),
13
+ };
8
14
  static description = 'Create a new tenant in a workspace';
9
15
  static examples = [
10
- `$ xano tenant create --display "Production"
16
+ `$ xano tenant create "Production"
11
17
  Created tenant: Production (production) - ID: 42
12
18
  `,
13
- `$ xano tenant create --display "Staging" --description "Staging env" --cluster-id 1 --platform-id 1 --license tier2 -o json`,
19
+ `$ xano tenant create "Staging" --description "Staging env" --cluster_id 1 --platform_id 1 --license tier2 -o json`,
14
20
  ];
15
21
  static flags = {
16
22
  ...BaseCommand.baseFlags,
17
- 'cluster-id': Flags.integer({
23
+ cluster_id: Flags.integer({
18
24
  description: 'Cluster ID to deploy to (required for tier2/tier3)',
19
25
  required: false,
20
26
  }),
@@ -23,14 +29,14 @@ Created tenant: Production (production) - ID: 42
23
29
  description: 'Tenant description',
24
30
  required: false,
25
31
  }),
26
- display: Flags.string({
27
- description: 'Display name for the tenant',
28
- required: true,
29
- }),
30
32
  domain: Flags.string({
31
33
  description: 'Custom domain for the tenant',
32
34
  required: false,
33
35
  }),
36
+ ephemeral: Flags.boolean({
37
+ default: false,
38
+ description: 'Mark tenant as ephemeral (allows push operations)',
39
+ }),
34
40
  ingress: Flags.boolean({
35
41
  allowNo: true,
36
42
  default: true,
@@ -49,7 +55,7 @@ Created tenant: Production (production) - ID: 42
49
55
  options: ['summary', 'json'],
50
56
  required: false,
51
57
  }),
52
- 'platform-id': Flags.integer({
58
+ platform_id: Flags.integer({
53
59
  description: 'Platform ID to use',
54
60
  required: false,
55
61
  }),
@@ -65,7 +71,7 @@ Created tenant: Production (production) - ID: 42
65
71
  }),
66
72
  };
67
73
  async run() {
68
- const { flags } = await this.parse(TenantCreate);
74
+ const { args, flags } = await this.parse(TenantCreate);
69
75
  const profileName = flags.profile || this.getDefaultProfile();
70
76
  const credentials = this.loadCredentials();
71
77
  if (!(profileName in credentials.profiles)) {
@@ -84,7 +90,8 @@ Created tenant: Production (production) - ID: 42
84
90
  this.error('No workspace ID provided. Use --workspace flag or set one in your profile.');
85
91
  }
86
92
  const body = {
87
- display: flags.display,
93
+ display: args.display,
94
+ ephemeral: flags.ephemeral,
88
95
  ingress: flags.ingress,
89
96
  license: flags.license,
90
97
  tag: [],
@@ -92,10 +99,12 @@ Created tenant: Production (production) - ID: 42
92
99
  };
93
100
  if (flags.description)
94
101
  body.description = flags.description;
95
- if (flags['cluster-id'])
96
- body.cluster_id = flags['cluster-id'];
97
- if (flags['platform-id'])
98
- body.platform_id = flags['platform-id'];
102
+ if (flags.cluster_id) {
103
+ body.cluster_id = flags.cluster_id;
104
+ body.license = 'tier3';
105
+ }
106
+ if (flags.platform_id)
107
+ body.platform_id = flags.platform_id;
99
108
  if (flags.domain)
100
109
  body.domain = flags.domain;
101
110
  const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant`;
@@ -103,8 +112,8 @@ Created tenant: Production (production) - ID: 42
103
112
  const response = await this.verboseFetch(apiUrl, {
104
113
  body: JSON.stringify(body),
105
114
  headers: {
106
- 'accept': 'application/json',
107
- 'Authorization': `Bearer ${profile.access_token}`,
115
+ accept: 'application/json',
116
+ Authorization: `Bearer ${profile.access_token}`,
108
117
  'Content-Type': 'application/json',
109
118
  },
110
119
  method: 'POST',
@@ -113,7 +122,7 @@ Created tenant: Production (production) - ID: 42
113
122
  const errorText = await response.text();
114
123
  this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
115
124
  }
116
- const tenant = await response.json();
125
+ const tenant = (await response.json());
117
126
  if (flags.output === 'json') {
118
127
  this.log(JSON.stringify(tenant, null, 2));
119
128
  }
@@ -137,8 +146,7 @@ Created tenant: Production (production) - ID: 42
137
146
  const configDir = path.join(os.homedir(), '.xano');
138
147
  const credentialsPath = path.join(configDir, 'credentials.yaml');
139
148
  if (!fs.existsSync(credentialsPath)) {
140
- this.error(`Credentials file not found at ${credentialsPath}\n` +
141
- `Create a profile using 'xano profile create'`);
149
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
142
150
  }
143
151
  try {
144
152
  const fileContent = fs.readFileSync(credentialsPath, 'utf8');
@@ -7,7 +7,7 @@ export default class TenantDeployPlatform extends BaseCommand {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
- 'platform-id': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ platform_id: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
11
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
13
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -13,10 +13,10 @@ export default class TenantDeployPlatform extends BaseCommand {
13
13
  };
14
14
  static description = 'Deploy a platform version to a tenant';
15
15
  static examples = [
16
- `$ xano tenant deploy-platform t1234-abcd-xyz1 --platform-id 5
16
+ `$ xano tenant deploy_platform t1234-abcd-xyz1 --platform_id 5
17
17
  Deployed platform 5 to tenant: My Tenant (my-tenant)
18
18
  `,
19
- `$ xano tenant deploy-platform t1234-abcd-xyz1 --platform-id 5 -o json`,
19
+ `$ xano tenant deploy_platform t1234-abcd-xyz1 --platform_id 5 -o json`,
20
20
  ];
21
21
  static flags = {
22
22
  ...BaseCommand.baseFlags,
@@ -27,7 +27,7 @@ Deployed platform 5 to tenant: My Tenant (my-tenant)
27
27
  options: ['summary', 'json'],
28
28
  required: false,
29
29
  }),
30
- 'platform-id': Flags.integer({
30
+ platform_id: Flags.integer({
31
31
  description: 'Platform ID to deploy',
32
32
  required: true,
33
33
  }),
@@ -57,14 +57,14 @@ Deployed platform 5 to tenant: My Tenant (my-tenant)
57
57
  this.error('No workspace ID provided. Use --workspace flag or set one in your profile.');
58
58
  }
59
59
  const tenantName = args.tenant_name;
60
- const platformId = flags['platform-id'];
60
+ const platformId = flags.platform_id;
61
61
  const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant/${tenantName}/platform/deploy`;
62
62
  try {
63
63
  const response = await this.verboseFetch(apiUrl, {
64
64
  body: JSON.stringify({ platform_id: platformId }),
65
65
  headers: {
66
- 'accept': 'application/json',
67
- 'Authorization': `Bearer ${profile.access_token}`,
66
+ accept: 'application/json',
67
+ Authorization: `Bearer ${profile.access_token}`,
68
68
  'Content-Type': 'application/json',
69
69
  },
70
70
  method: 'POST',
@@ -73,7 +73,7 @@ Deployed platform 5 to tenant: My Tenant (my-tenant)
73
73
  const errorText = await response.text();
74
74
  this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
75
75
  }
76
- const tenant = await response.json();
76
+ const tenant = (await response.json());
77
77
  if (flags.output === 'json') {
78
78
  this.log(JSON.stringify(tenant, null, 2));
79
79
  }
@@ -98,8 +98,7 @@ Deployed platform 5 to tenant: My Tenant (my-tenant)
98
98
  const configDir = path.join(os.homedir(), '.xano');
99
99
  const credentialsPath = path.join(configDir, 'credentials.yaml');
100
100
  if (!fs.existsSync(credentialsPath)) {
101
- this.error(`Credentials file not found at ${credentialsPath}\n` +
102
- `Create a profile using 'xano profile create'`);
101
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
103
102
  }
104
103
  try {
105
104
  const fileContent = fs.readFileSync(credentialsPath, 'utf8');
@@ -7,7 +7,7 @@ export default class TenantDeployRelease extends BaseCommand {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
- 'release-id': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ release: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
11
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
13
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -13,10 +13,10 @@ export default class TenantDeployRelease extends BaseCommand {
13
13
  };
14
14
  static description = 'Deploy a release to a tenant';
15
15
  static examples = [
16
- `$ xano tenant deploy-release t1234-abcd-xyz1 --release-id 10
17
- Deployed release 10 to tenant: My Tenant (my-tenant)
16
+ `$ xano tenant deploy_release t1234-abcd-xyz1 --release v1.0
17
+ Deployed release "v1.0" to tenant: My Tenant (my-tenant)
18
18
  `,
19
- `$ xano tenant deploy-release t1234-abcd-xyz1 --release-id 10 -o json`,
19
+ `$ xano tenant deploy_release t1234-abcd-xyz1 --release v1.0 -o json`,
20
20
  ];
21
21
  static flags = {
22
22
  ...BaseCommand.baseFlags,
@@ -27,8 +27,9 @@ Deployed release 10 to tenant: My Tenant (my-tenant)
27
27
  options: ['summary', 'json'],
28
28
  required: false,
29
29
  }),
30
- 'release-id': Flags.integer({
31
- description: 'Release ID to deploy',
30
+ release: Flags.string({
31
+ char: 'r',
32
+ description: 'Release name to deploy',
32
33
  required: true,
33
34
  }),
34
35
  workspace: Flags.string({
@@ -56,15 +57,15 @@ Deployed release 10 to tenant: My Tenant (my-tenant)
56
57
  if (!workspaceId) {
57
58
  this.error('No workspace ID provided. Use --workspace flag or set one in your profile.');
58
59
  }
60
+ const releaseName = flags.release;
59
61
  const tenantName = args.tenant_name;
60
- const releaseId = flags['release-id'];
61
62
  const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant/${tenantName}/deploy`;
62
63
  try {
63
64
  const response = await this.verboseFetch(apiUrl, {
64
- body: JSON.stringify({ release_id: releaseId }),
65
+ body: JSON.stringify({ release_name: releaseName }),
65
66
  headers: {
66
- 'accept': 'application/json',
67
- 'Authorization': `Bearer ${profile.access_token}`,
67
+ accept: 'application/json',
68
+ Authorization: `Bearer ${profile.access_token}`,
68
69
  'Content-Type': 'application/json',
69
70
  },
70
71
  method: 'POST',
@@ -73,12 +74,12 @@ Deployed release 10 to tenant: My Tenant (my-tenant)
73
74
  const errorText = await response.text();
74
75
  this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
75
76
  }
76
- const tenant = await response.json();
77
+ const tenant = (await response.json());
77
78
  if (flags.output === 'json') {
78
79
  this.log(JSON.stringify(tenant, null, 2));
79
80
  }
80
81
  else {
81
- this.log(`Deployed release ${releaseId} to tenant: ${tenant.display || tenant.name} (${tenant.name})`);
82
+ this.log(`Deployed release "${releaseName}" to tenant: ${tenant.display || tenant.name} (${tenant.name})`);
82
83
  if (tenant.state)
83
84
  this.log(` State: ${tenant.state}`);
84
85
  if (tenant.release?.name)
@@ -98,8 +99,7 @@ Deployed release 10 to tenant: My Tenant (my-tenant)
98
99
  const configDir = path.join(os.homedir(), '.xano');
99
100
  const credentialsPath = path.join(configDir, 'credentials.yaml');
100
101
  if (!fs.existsSync(credentialsPath)) {
101
- this.error(`Credentials file not found at ${credentialsPath}\n` +
102
- `Create a profile using 'xano profile create'`);
102
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
103
103
  }
104
104
  try {
105
105
  const fileContent = fs.readFileSync(credentialsPath, 'utf8');
@@ -0,0 +1,19 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class TenantEnvDelete 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
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, 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
+ private confirm;
18
+ private loadCredentials;
19
+ }