@xano/cli 0.0.95-beta.1 → 0.0.95-beta.11

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 (86) hide show
  1. package/README.md +22 -9
  2. package/dist/base-command.d.ts +30 -0
  3. package/dist/base-command.js +61 -0
  4. package/dist/commands/auth/index.js +1 -1
  5. package/dist/commands/profile/create/index.js +2 -2
  6. package/dist/commands/profile/edit/index.js +2 -2
  7. package/dist/commands/profile/me/index.js +21 -2
  8. package/dist/commands/profile/wizard/index.js +3 -3
  9. package/dist/commands/profile/workspace/set/index.js +1 -1
  10. package/dist/commands/release/deploy/index.d.ts +17 -0
  11. package/dist/commands/release/deploy/index.js +107 -0
  12. package/dist/commands/{ephemeral → sandbox}/env/delete/index.d.ts +1 -4
  13. package/dist/commands/{ephemeral → sandbox}/env/delete/index.js +18 -36
  14. package/dist/commands/{ephemeral → sandbox}/env/get/index.d.ts +1 -4
  15. package/dist/commands/sandbox/env/get/index.js +63 -0
  16. package/dist/commands/{ephemeral → sandbox}/env/get_all/index.d.ts +1 -4
  17. package/dist/commands/sandbox/env/get_all/index.js +76 -0
  18. package/dist/commands/{ephemeral → sandbox}/env/list/index.d.ts +1 -4
  19. package/dist/commands/sandbox/env/list/index.js +65 -0
  20. package/dist/commands/{ephemeral → sandbox}/env/set/index.d.ts +1 -4
  21. package/dist/commands/sandbox/env/set/index.js +72 -0
  22. package/dist/commands/{ephemeral → sandbox}/env/set_all/index.d.ts +1 -4
  23. package/dist/commands/{ephemeral → sandbox}/env/set_all/index.js +17 -35
  24. package/dist/commands/{ephemeral → sandbox}/get/index.d.ts +1 -4
  25. package/dist/commands/sandbox/get/index.js +61 -0
  26. package/dist/commands/sandbox/impersonate/index.d.ts +5 -0
  27. package/dist/commands/sandbox/impersonate/index.js +5 -0
  28. package/dist/commands/{ephemeral → sandbox}/license/get/index.d.ts +1 -4
  29. package/dist/commands/sandbox/license/get/index.js +76 -0
  30. package/dist/commands/{ephemeral → sandbox}/license/set/index.d.ts +1 -4
  31. package/dist/commands/{ephemeral → sandbox}/license/set/index.js +18 -36
  32. package/dist/commands/{ephemeral → sandbox}/pull/index.d.ts +1 -2
  33. package/dist/commands/{ephemeral → sandbox}/pull/index.js +11 -28
  34. package/dist/commands/{ephemeral → sandbox}/push/index.d.ts +2 -2
  35. package/dist/commands/{ephemeral → sandbox}/push/index.js +37 -31
  36. package/dist/commands/{ephemeral/delete → sandbox/reset}/index.d.ts +1 -5
  37. package/dist/commands/sandbox/reset/index.js +69 -0
  38. package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.d.ts +1 -4
  39. package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.js +15 -33
  40. package/dist/commands/{ephemeral/unit_test/run_all → sandbox/unit_test/list}/index.d.ts +1 -2
  41. package/dist/commands/{ephemeral → sandbox}/unit_test/list/index.js +10 -26
  42. package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.d.ts +1 -2
  43. package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.js +9 -25
  44. package/dist/commands/{ephemeral/unit_test/list → sandbox/unit_test/run_all}/index.d.ts +1 -2
  45. package/dist/commands/{ephemeral → sandbox}/unit_test/run_all/index.js +7 -23
  46. package/dist/commands/{ephemeral/workflow_test/get → sandbox/workflow_test/delete}/index.d.ts +1 -2
  47. package/dist/commands/{ephemeral → sandbox}/workflow_test/delete/index.js +9 -25
  48. package/dist/commands/{ephemeral/workflow_test/run → sandbox/workflow_test/get}/index.d.ts +1 -2
  49. package/dist/commands/{ephemeral → sandbox}/workflow_test/get/index.js +8 -27
  50. package/dist/commands/{ephemeral/workflow_test/run_all → sandbox/workflow_test/list}/index.d.ts +1 -2
  51. package/dist/commands/{ephemeral → sandbox}/workflow_test/list/index.js +11 -27
  52. package/dist/commands/{ephemeral/workflow_test/delete → sandbox/workflow_test/run}/index.d.ts +1 -2
  53. package/dist/commands/{ephemeral → sandbox}/workflow_test/run/index.js +9 -25
  54. package/dist/commands/{ephemeral/workflow_test/list → sandbox/workflow_test/run_all}/index.d.ts +1 -2
  55. package/dist/commands/{ephemeral → sandbox}/workflow_test/run_all/index.js +7 -23
  56. package/dist/commands/tenant/create/index.d.ts +2 -1
  57. package/dist/commands/tenant/create/index.js +23 -6
  58. package/dist/commands/tenant/get/index.js +2 -2
  59. package/dist/commands/tenant/list/index.js +2 -2
  60. package/dist/commands/tenant/push/index.js +0 -34
  61. package/dist/commands/workspace/edit/index.d.ts +1 -0
  62. package/dist/commands/workspace/edit/index.js +16 -6
  63. package/dist/commands/workspace/get/index.js +9 -7
  64. package/dist/commands/workspace/list/index.d.ts +1 -0
  65. package/dist/commands/workspace/list/index.js +14 -7
  66. package/dist/commands/workspace/push/index.d.ts +1 -0
  67. package/dist/commands/workspace/push/index.js +60 -6
  68. package/dist/utils/reference-checker.d.ts +45 -0
  69. package/dist/utils/reference-checker.js +137 -0
  70. package/oclif.manifest.json +2525 -2894
  71. package/package.json +8 -8
  72. package/dist/commands/ephemeral/access/index.d.ts +0 -15
  73. package/dist/commands/ephemeral/access/index.js +0 -78
  74. package/dist/commands/ephemeral/create/index.d.ts +0 -17
  75. package/dist/commands/ephemeral/create/index.js +0 -102
  76. package/dist/commands/ephemeral/delete/index.js +0 -99
  77. package/dist/commands/ephemeral/env/get/index.js +0 -81
  78. package/dist/commands/ephemeral/env/get_all/index.js +0 -94
  79. package/dist/commands/ephemeral/env/list/index.js +0 -83
  80. package/dist/commands/ephemeral/env/set/index.js +0 -90
  81. package/dist/commands/ephemeral/get/index.js +0 -102
  82. package/dist/commands/ephemeral/license/get/index.js +0 -94
  83. package/dist/commands/ephemeral/list/index.d.ts +0 -15
  84. package/dist/commands/ephemeral/list/index.js +0 -109
  85. package/dist/commands/ephemeral/shared/index.d.ts +0 -15
  86. package/dist/commands/ephemeral/shared/index.js +0 -108
@@ -1,5 +1,5 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class EphemeralWorkflowTestGet extends BaseCommand {
2
+ export default class SandboxWorkflowTestDelete extends BaseCommand {
3
3
  static args: {
4
4
  workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
5
  max?: number;
@@ -10,7 +10,6 @@ export default class EphemeralWorkflowTestGet extends BaseCommand {
10
10
  static examples: string[];
11
11
  static flags: {
12
12
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
13
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
14
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
15
  };
@@ -1,18 +1,18 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../../base-command.js';
3
- export default class EphemeralWorkflowTestDelete extends BaseCommand {
3
+ export default class SandboxWorkflowTestDelete extends BaseCommand {
4
4
  static args = {
5
5
  workflow_test_id: Args.integer({
6
6
  description: 'ID of the workflow test to delete',
7
7
  required: true,
8
8
  }),
9
9
  };
10
- static description = 'Delete a workflow test for an ephemeral tenant';
10
+ static description = 'Delete a workflow test for a sandbox environment';
11
11
  static examples = [
12
- `$ xano ephemeral workflow-test delete 42 -t e1a2-b3c4-x5y6
12
+ `$ xano sandbox workflow-test delete 42
13
13
  Deleted workflow test 42
14
14
  `,
15
- `$ xano ephemeral workflow-test delete 42 -t e1a2-b3c4-x5y6 -o json`,
15
+ `$ xano sandbox workflow-test delete 42 -o json`,
16
16
  ];
17
17
  static flags = {
18
18
  ...BaseCommand.baseFlags,
@@ -23,27 +23,11 @@ Deleted workflow test 42
23
23
  options: ['summary', 'json'],
24
24
  required: false,
25
25
  }),
26
- tenant: Flags.string({
27
- char: 't',
28
- description: 'Ephemeral tenant name',
29
- required: true,
30
- }),
31
26
  };
32
27
  async run() {
33
- const { args, flags } = await this.parse(EphemeralWorkflowTestDelete);
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.\nCreate 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(flags.tenant)}/workflow_test/${args.workflow_test_id}`;
28
+ const { args, flags } = await this.parse(SandboxWorkflowTestDelete);
29
+ const { profile } = this.resolveProfile(flags);
30
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test/${args.workflow_test_id}`;
47
31
  try {
48
32
  const response = await this.verboseFetch(apiUrl, {
49
33
  headers: {
@@ -53,8 +37,8 @@ Deleted workflow test 42
53
37
  method: 'DELETE',
54
38
  }, flags.verbose, profile.access_token);
55
39
  if (!response.ok) {
56
- const errorText = await response.text();
57
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
40
+ const message = await this.parseApiError(response, 'API request failed');
41
+ this.error(message);
58
42
  }
59
43
  if (flags.output === 'json') {
60
44
  this.log(JSON.stringify({ deleted: true, workflow_test_id: args.workflow_test_id }, null, 2));
@@ -1,5 +1,5 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class EphemeralWorkflowTestRun extends BaseCommand {
2
+ export default class SandboxWorkflowTestGet extends BaseCommand {
3
3
  static args: {
4
4
  workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
5
  max?: number;
@@ -10,7 +10,6 @@ export default class EphemeralWorkflowTestRun extends BaseCommand {
10
10
  static examples: string[];
11
11
  static flags: {
12
12
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
13
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
14
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
15
  };
@@ -1,17 +1,14 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../../base-command.js';
3
- export default class EphemeralWorkflowTestGet extends BaseCommand {
3
+ export default class SandboxWorkflowTestGet extends BaseCommand {
4
4
  static args = {
5
5
  workflow_test_id: Args.integer({
6
6
  description: 'ID of the workflow test',
7
7
  required: true,
8
8
  }),
9
9
  };
10
- static description = 'Get a workflow test for an ephemeral tenant';
11
- static examples = [
12
- `$ xano ephemeral workflow-test get 42 -t e1a2-b3c4-x5y6`,
13
- `$ xano ephemeral workflow-test get 42 -t e1a2-b3c4-x5y6 -o json`,
14
- ];
10
+ static description = 'Get a workflow test for a sandbox environment';
11
+ static examples = [`$ xano sandbox workflow-test get 42`, `$ xano sandbox workflow-test get 42 -o json`];
15
12
  static flags = {
16
13
  ...BaseCommand.baseFlags,
17
14
  output: Flags.string({
@@ -21,27 +18,11 @@ export default class EphemeralWorkflowTestGet extends BaseCommand {
21
18
  options: ['summary', 'json'],
22
19
  required: false,
23
20
  }),
24
- tenant: Flags.string({
25
- char: 't',
26
- description: 'Ephemeral tenant name',
27
- required: true,
28
- }),
29
21
  };
30
22
  async run() {
31
- const { args, flags } = await this.parse(EphemeralWorkflowTestGet);
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.\nCreate 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 apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(flags.tenant)}/workflow_test/${args.workflow_test_id}`;
23
+ const { args, flags } = await this.parse(SandboxWorkflowTestGet);
24
+ const { profile } = this.resolveProfile(flags);
25
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test/${args.workflow_test_id}`;
45
26
  try {
46
27
  const response = await this.verboseFetch(apiUrl, {
47
28
  headers: {
@@ -51,8 +32,8 @@ export default class EphemeralWorkflowTestGet extends BaseCommand {
51
32
  method: 'GET',
52
33
  }, flags.verbose, profile.access_token);
53
34
  if (!response.ok) {
54
- const errorText = await response.text();
55
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
35
+ const message = await this.parseApiError(response, 'API request failed');
36
+ this.error(message);
56
37
  }
57
38
  const test = await response.json();
58
39
  if (flags.output === 'json') {
@@ -1,11 +1,10 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class EphemeralWorkflowTestRunAll extends BaseCommand {
2
+ export default class SandboxWorkflowTestList extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
- tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
8
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
9
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
10
  };
@@ -1,13 +1,13 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../../base-command.js';
3
- export default class EphemeralWorkflowTestList extends BaseCommand {
4
- static description = 'List workflow tests for an ephemeral tenant';
3
+ export default class SandboxWorkflowTestList extends BaseCommand {
4
+ static description = 'List workflow tests for a sandbox environment';
5
5
  static examples = [
6
- `$ xano ephemeral workflow-test list -t e1a2-b3c4-x5y6
7
- Workflow tests for tenant e1a2-b3c4-x5y6:
6
+ `$ xano sandbox workflow-test list
7
+ Workflow tests:
8
8
  - my-test (ID: 1)
9
9
  `,
10
- `$ xano ephemeral workflow-test list -t e1a2-b3c4-x5y6 -o json`,
10
+ `$ xano sandbox workflow-test list -o json`,
11
11
  ];
12
12
  static flags = {
13
13
  ...BaseCommand.baseFlags,
@@ -23,31 +23,15 @@ Workflow tests for tenant e1a2-b3c4-x5y6:
23
23
  options: ['summary', 'json'],
24
24
  required: false,
25
25
  }),
26
- tenant: Flags.string({
27
- char: 't',
28
- description: 'Ephemeral tenant name',
29
- required: true,
30
- }),
31
26
  };
32
27
  async run() {
33
- const { flags } = await this.parse(EphemeralWorkflowTestList);
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.\nCreate 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
- }
28
+ const { flags } = await this.parse(SandboxWorkflowTestList);
29
+ const { profile } = this.resolveProfile(flags);
46
30
  const params = new URLSearchParams();
47
31
  params.set('per_page', '10000');
48
32
  if (flags.branch)
49
33
  params.set('branch', flags.branch);
50
- const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(flags.tenant)}/workflow_test?${params}`;
34
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test?${params}`;
51
35
  try {
52
36
  const response = await this.verboseFetch(apiUrl, {
53
37
  headers: {
@@ -57,8 +41,8 @@ Workflow tests for tenant e1a2-b3c4-x5y6:
57
41
  method: 'GET',
58
42
  }, flags.verbose, profile.access_token);
59
43
  if (!response.ok) {
60
- const errorText = await response.text();
61
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
44
+ const message = await this.parseApiError(response, 'API request failed');
45
+ this.error(message);
62
46
  }
63
47
  const data = (await response.json());
64
48
  let tests;
@@ -79,7 +63,7 @@ Workflow tests for tenant e1a2-b3c4-x5y6:
79
63
  this.log('No workflow tests found');
80
64
  }
81
65
  else {
82
- this.log(`Workflow tests for tenant ${flags.tenant}:`);
66
+ this.log(`Workflow tests for sandbox environment:`);
83
67
  for (const test of tests) {
84
68
  this.log(` - ${test.name} (ID: ${test.id})`);
85
69
  }
@@ -1,5 +1,5 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class EphemeralWorkflowTestDelete extends BaseCommand {
2
+ export default class SandboxWorkflowTestRun extends BaseCommand {
3
3
  static args: {
4
4
  workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
5
  max?: number;
@@ -10,7 +10,6 @@ export default class EphemeralWorkflowTestDelete extends BaseCommand {
10
10
  static examples: string[];
11
11
  static flags: {
12
12
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
13
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
14
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
15
  };
@@ -1,19 +1,19 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../../base-command.js';
3
- export default class EphemeralWorkflowTestRun extends BaseCommand {
3
+ export default class SandboxWorkflowTestRun extends BaseCommand {
4
4
  static args = {
5
5
  workflow_test_id: Args.integer({
6
6
  description: 'ID of the workflow test to run',
7
7
  required: true,
8
8
  }),
9
9
  };
10
- static description = 'Run a workflow test for an ephemeral tenant';
10
+ static description = 'Run a workflow test for a sandbox environment';
11
11
  static examples = [
12
- `$ xano ephemeral workflow-test run 42 -t e1a2-b3c4-x5y6
12
+ `$ xano sandbox workflow-test run 42
13
13
  Running workflow test 42...
14
14
  Result: PASS (0.25s)
15
15
  `,
16
- `$ xano ephemeral workflow-test run 42 -t e1a2-b3c4-x5y6 -o json`,
16
+ `$ xano sandbox workflow-test run 42 -o json`,
17
17
  ];
18
18
  static flags = {
19
19
  ...BaseCommand.baseFlags,
@@ -24,27 +24,11 @@ Result: PASS (0.25s)
24
24
  options: ['summary', 'json'],
25
25
  required: false,
26
26
  }),
27
- tenant: Flags.string({
28
- char: 't',
29
- description: 'Ephemeral tenant name',
30
- required: true,
31
- }),
32
27
  };
33
28
  async run() {
34
- const { args, flags } = await this.parse(EphemeralWorkflowTestRun);
35
- const profileName = flags.profile || this.getDefaultProfile();
36
- const credentials = this.loadCredentialsFile();
37
- if (!credentials || !(profileName in credentials.profiles)) {
38
- this.error(`Profile '${profileName}' not found.\nCreate a profile using 'xano profile create'`);
39
- }
40
- const profile = credentials.profiles[profileName];
41
- if (!profile.instance_origin) {
42
- this.error(`Profile '${profileName}' is missing instance_origin`);
43
- }
44
- if (!profile.access_token) {
45
- this.error(`Profile '${profileName}' is missing access_token`);
46
- }
47
- const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(flags.tenant)}/workflow_test/${args.workflow_test_id}/run`;
29
+ const { args, flags } = await this.parse(SandboxWorkflowTestRun);
30
+ const { profile } = this.resolveProfile(flags);
31
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test/${args.workflow_test_id}/run`;
48
32
  try {
49
33
  if (flags.output === 'summary') {
50
34
  this.log(`Running workflow test ${args.workflow_test_id}...`);
@@ -58,8 +42,8 @@ Result: PASS (0.25s)
58
42
  method: 'POST',
59
43
  }, flags.verbose, profile.access_token);
60
44
  if (!response.ok) {
61
- const errorText = await response.text();
62
- this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
45
+ const message = await this.parseApiError(response, 'API request failed');
46
+ this.error(message);
63
47
  }
64
48
  const result = (await response.json());
65
49
  if (flags.output === 'json') {
@@ -1,11 +1,10 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class EphemeralWorkflowTestList extends BaseCommand {
2
+ export default class SandboxWorkflowTestRunAll extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
- tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
8
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
9
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
10
  };
@@ -1,9 +1,9 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../../base-command.js';
3
- export default class EphemeralWorkflowTestRunAll extends BaseCommand {
4
- static description = 'Run all workflow tests for an ephemeral tenant';
3
+ export default class SandboxWorkflowTestRunAll extends BaseCommand {
4
+ static description = 'Run all workflow tests for a sandbox environment';
5
5
  static examples = [
6
- `$ xano ephemeral workflow-test run-all -t e1a2-b3c4-x5y6
6
+ `$ xano sandbox workflow-test run-all
7
7
  Running 3 workflow tests...
8
8
 
9
9
  PASS my-test (0.25s)
@@ -12,7 +12,7 @@ FAIL data-check (0.10s)
12
12
 
13
13
  Results: 2 passed, 1 failed
14
14
  `,
15
- `$ xano ephemeral workflow-test run-all -t e1a2-b3c4-x5y6 -o json`,
15
+ `$ xano sandbox workflow-test run-all -o json`,
16
16
  ];
17
17
  static flags = {
18
18
  ...BaseCommand.baseFlags,
@@ -28,27 +28,11 @@ Results: 2 passed, 1 failed
28
28
  options: ['summary', 'json'],
29
29
  required: false,
30
30
  }),
31
- tenant: Flags.string({
32
- char: 't',
33
- description: 'Ephemeral tenant name',
34
- required: true,
35
- }),
36
31
  };
37
32
  async run() {
38
- const { flags } = await this.parse(EphemeralWorkflowTestRunAll);
39
- const profileName = flags.profile || this.getDefaultProfile();
40
- const credentials = this.loadCredentialsFile();
41
- if (!credentials || !(profileName in credentials.profiles)) {
42
- this.error(`Profile '${profileName}' not found.\nCreate a profile using 'xano profile create'`);
43
- }
44
- const profile = credentials.profiles[profileName];
45
- if (!profile.instance_origin) {
46
- this.error(`Profile '${profileName}' is missing instance_origin`);
47
- }
48
- if (!profile.access_token) {
49
- this.error(`Profile '${profileName}' is missing access_token`);
50
- }
51
- const baseUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(flags.tenant)}/workflow_test`;
33
+ const { flags } = await this.parse(SandboxWorkflowTestRunAll);
34
+ const { profile } = this.resolveProfile(flags);
35
+ const baseUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test`;
52
36
  try {
53
37
  // Step 1: List all workflow tests
54
38
  const listParams = new URLSearchParams();
@@ -10,9 +10,10 @@ export default class TenantCreate extends BaseCommand {
10
10
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
11
  domain: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  ingress: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- license: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ license: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
14
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
15
  platform_id: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
17
  tasks: import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
18
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
19
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -16,7 +16,8 @@ export default class TenantCreate extends BaseCommand {
16
16
  `$ xano tenant create "Production"
17
17
  Created tenant: Production (production) - ID: 42
18
18
  `,
19
- `$ xano tenant create "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 --type tier2 -o json`,
20
+ `$ xano tenant create "Staging" --type tier2 --cluster_id 1 --license ./license.yaml`,
20
21
  ];
21
22
  static flags = {
22
23
  ...BaseCommand.baseFlags,
@@ -39,9 +40,8 @@ Created tenant: Production (production) - ID: 42
39
40
  description: 'Enable ingress',
40
41
  }),
41
42
  license: Flags.string({
42
- default: 'tier1',
43
- description: 'License tier',
44
- options: ['tier1', 'tier2', 'tier3'],
43
+ char: 'l',
44
+ description: 'Path to a license override file to apply during creation',
45
45
  required: false,
46
46
  }),
47
47
  output: Flags.string({
@@ -55,6 +55,12 @@ Created tenant: Production (production) - ID: 42
55
55
  description: 'Platform ID to use',
56
56
  required: false,
57
57
  }),
58
+ type: Flags.string({
59
+ default: 'tier1',
60
+ description: 'Tenant type',
61
+ options: ['tier1', 'tier2', 'tier3'],
62
+ required: false,
63
+ }),
58
64
  tasks: Flags.boolean({
59
65
  allowNo: true,
60
66
  default: true,
@@ -88,7 +94,7 @@ Created tenant: Production (production) - ID: 42
88
94
  const body = {
89
95
  display: args.display,
90
96
  ingress: flags.ingress,
91
- license: flags.license,
97
+ license: flags.type,
92
98
  tag: [],
93
99
  tasks: flags.tasks,
94
100
  };
@@ -102,7 +108,16 @@ Created tenant: Production (production) - ID: 42
102
108
  body.platform_id = flags.platform_id;
103
109
  if (flags.domain)
104
110
  body.domain = flags.domain;
105
- if (flags.license === 'tier2' || flags.license === 'tier3' || flags.cluster_id) {
111
+ if (flags.license) {
112
+ const licensePath = path.resolve(flags.license);
113
+ if (!fs.existsSync(licensePath)) {
114
+ this.error(`License file not found: ${licensePath}`);
115
+ }
116
+ const licenseContent = fs.readFileSync(licensePath, 'utf8');
117
+ body.license_overrides = yaml.load(licenseContent);
118
+ }
119
+ const effectiveType = flags.cluster_id ? 'tier3' : flags.type;
120
+ if (effectiveType === 'tier2' || effectiveType === 'tier3') {
106
121
  this.warn('This may take a few minutes. Please be patient.');
107
122
  }
108
123
  const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant`;
@@ -129,6 +144,8 @@ Created tenant: Production (production) - ID: 42
129
144
  if (tenant.state) {
130
145
  this.log(` State: ${tenant.state}`);
131
146
  }
147
+ if (flags.license)
148
+ this.log(` License: applied`);
132
149
  }
133
150
  }
134
151
  catch (error) {
@@ -99,8 +99,8 @@ Tenant: My Tenant (my-tenant)
99
99
  this.log(` Tasks: ${tenant.tasks}`);
100
100
  if (tenant.ingress !== undefined)
101
101
  this.log(` Ingress: ${tenant.ingress}`);
102
- if (tenant.ephemeral)
103
- this.log(` Ephemeral: ${tenant.ephemeral}`);
102
+ if (tenant.type)
103
+ this.log(` Type: ${tenant.type}`);
104
104
  if (tenant.deployed_at) {
105
105
  const d = new Date(tenant.deployed_at);
106
106
  const deployedDate = Number.isNaN(d.getTime()) ? tenant.deployed_at : d.toISOString().split('T')[0];
@@ -92,8 +92,8 @@ Tenants in workspace 5:
92
92
  for (const tenant of tenants) {
93
93
  const state = tenant.state ? ` [${tenant.state}]` : '';
94
94
  const license = tenant.license ? ` - ${tenant.license}` : '';
95
- const ephemeral = tenant.ephemeral ? ' [ephemeral]' : '';
96
- this.log(` - ${tenant.display || tenant.name} (${tenant.name})${state}${license}${ephemeral}`);
95
+ const typeLabel = tenant.type && tenant.type !== 'standard' ? ` [${tenant.type}]` : '';
96
+ this.log(` - ${tenant.display || tenant.name} (${tenant.name})${state}${license}${typeLabel}`);
97
97
  if (tenant.cluster?.name)
98
98
  this.log(` Cluster: ${tenant.cluster.name}`);
99
99
  const releaseName = typeof tenant.release === 'string' ? tenant.release : tenant.release?.name;
@@ -100,40 +100,6 @@ Truncate all table records before importing
100
100
  ` 2. Set it in your profile using: xano profile:edit ${profileName} -w <workspace_id>`);
101
101
  }
102
102
  const tenantName = flags.tenant;
103
- // Fetch tenant details and verify it's ephemeral
104
- const tenantApiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant/${tenantName}`;
105
- try {
106
- const tenantResponse = await this.verboseFetch(tenantApiUrl, {
107
- headers: {
108
- accept: 'application/json',
109
- Authorization: `Bearer ${profile.access_token}`,
110
- },
111
- method: 'GET',
112
- }, flags.verbose, profile.access_token);
113
- if (!tenantResponse.ok) {
114
- const errorText = await tenantResponse.text();
115
- this.error(`Failed to fetch tenant '${tenantName}' (${tenantResponse.status}): ${errorText}`);
116
- }
117
- const tenantData = (await tenantResponse.json());
118
- if (!tenantData.ephemeral) {
119
- this.error(`Tenant '${tenantName}' is not ephemeral. Push is only allowed for ephemeral tenants.\n` +
120
- `Create an ephemeral tenant with: xano ephemeral create "name"`);
121
- }
122
- }
123
- catch (error) {
124
- if (error instanceof Error && error.message.includes('is not ephemeral')) {
125
- throw error;
126
- }
127
- if (error instanceof Error && error.message.includes('Failed to fetch tenant')) {
128
- throw error;
129
- }
130
- if (error instanceof Error) {
131
- this.error(`Failed to verify tenant: ${error.message}`);
132
- }
133
- else {
134
- this.error(`Failed to verify tenant: ${String(error)}`);
135
- }
136
- }
137
103
  // Resolve the input directory
138
104
  const inputDir = path.resolve(args.directory);
139
105
  if (!fs.existsSync(inputDir)) {
@@ -9,6 +9,7 @@ export default class WorkspaceEdit extends BaseCommand {
9
9
  static description: string;
10
10
  static examples: string[];
11
11
  static flags: {
12
+ 'allow-push': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
13
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
14
  name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
15
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
@@ -35,6 +35,11 @@ Updated workspace: my-workspace (ID: 123)
35
35
  ];
36
36
  static flags = {
37
37
  ...BaseCommand.baseFlags,
38
+ 'allow-push': Flags.boolean({
39
+ allowNo: true,
40
+ description: 'Enable or disable direct CLI push to this workspace (not applicable on Free plan)',
41
+ required: false,
42
+ }),
38
43
  description: Flags.string({
39
44
  char: 'd',
40
45
  description: 'New description for the workspace',
@@ -102,9 +107,12 @@ Updated workspace: my-workspace (ID: 123)
102
107
  if (flags['require-token'] !== undefined) {
103
108
  body.documentation = { require_token: flags['require-token'] };
104
109
  }
110
+ if (flags['allow-push'] !== undefined) {
111
+ body.preferences = { allow_push: flags['allow-push'] };
112
+ }
105
113
  // Check if at least one field is being updated
106
114
  if (Object.keys(body).length === 0) {
107
- this.error('No fields specified to update. Use --name, --description, --swagger, or --require-token flags.\n' +
115
+ this.error('No fields specified to update. Use --name, --description, --swagger, --require-token, or --allow-push flags.\n' +
108
116
  'Example: xano workspace edit 123 --name "new-name"');
109
117
  }
110
118
  // Construct the API URL
@@ -114,8 +122,8 @@ Updated workspace: my-workspace (ID: 123)
114
122
  const response = await this.verboseFetch(apiUrl, {
115
123
  body: JSON.stringify(body),
116
124
  headers: {
117
- 'accept': 'application/json',
118
- 'Authorization': `Bearer ${profile.access_token}`,
125
+ accept: 'application/json',
126
+ Authorization: `Bearer ${profile.access_token}`,
119
127
  'Content-Type': 'application/json',
120
128
  },
121
129
  method: 'PUT',
@@ -124,7 +132,7 @@ Updated workspace: my-workspace (ID: 123)
124
132
  const errorText = await response.text();
125
133
  this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
126
134
  }
127
- const workspace = await response.json();
135
+ const workspace = (await response.json());
128
136
  // Output results
129
137
  if (flags.output === 'json') {
130
138
  this.log(JSON.stringify(workspace, null, 2));
@@ -141,6 +149,9 @@ Updated workspace: my-workspace (ID: 123)
141
149
  if (workspace.documentation?.require_token !== undefined) {
142
150
  this.log(` Require Token: ${workspace.documentation.require_token}`);
143
151
  }
152
+ if (workspace.preferences?.allow_push !== undefined) {
153
+ this.log(` Allow Push: ${workspace.preferences.allow_push}`);
154
+ }
144
155
  }
145
156
  }
146
157
  catch (error) {
@@ -157,8 +168,7 @@ Updated workspace: my-workspace (ID: 123)
157
168
  const credentialsPath = path.join(configDir, 'credentials.yaml');
158
169
  // Check if credentials file exists
159
170
  if (!fs.existsSync(credentialsPath)) {
160
- this.error(`Credentials file not found at ${credentialsPath}\n` +
161
- `Create a profile using 'xano profile create'`);
171
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
162
172
  }
163
173
  // Read credentials file
164
174
  try {