@xano/cli 0.0.94 → 0.0.95-beta.10

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 +28 -1
  2. package/dist/base-command.d.ts +25 -0
  3. package/dist/base-command.js +37 -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/sandbox/env/delete/index.d.ts +14 -0
  13. package/dist/commands/sandbox/env/delete/index.js +87 -0
  14. package/dist/commands/sandbox/env/get/index.d.ts +12 -0
  15. package/dist/commands/sandbox/env/get/index.js +63 -0
  16. package/dist/commands/sandbox/env/get_all/index.d.ts +13 -0
  17. package/dist/commands/sandbox/env/get_all/index.js +76 -0
  18. package/dist/commands/sandbox/env/list/index.d.ts +11 -0
  19. package/dist/commands/sandbox/env/list/index.js +65 -0
  20. package/dist/commands/sandbox/env/set/index.d.ts +13 -0
  21. package/dist/commands/sandbox/env/set/index.js +72 -0
  22. package/dist/commands/sandbox/env/set_all/index.d.ts +13 -0
  23. package/dist/commands/sandbox/env/set_all/index.js +84 -0
  24. package/dist/commands/sandbox/get/index.d.ts +11 -0
  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/sandbox/license/get/index.d.ts +13 -0
  29. package/dist/commands/sandbox/license/get/index.js +76 -0
  30. package/dist/commands/sandbox/license/set/index.d.ts +14 -0
  31. package/dist/commands/sandbox/license/set/index.js +93 -0
  32. package/dist/commands/sandbox/pull/index.d.ts +17 -0
  33. package/dist/commands/sandbox/pull/index.js +180 -0
  34. package/dist/commands/sandbox/push/index.d.ts +18 -0
  35. package/dist/commands/sandbox/push/index.js +141 -0
  36. package/dist/commands/sandbox/reset/index.d.ts +12 -0
  37. package/dist/commands/sandbox/reset/index.js +69 -0
  38. package/dist/commands/sandbox/review/index.d.ts +13 -0
  39. package/dist/commands/sandbox/review/index.js +92 -0
  40. package/dist/commands/sandbox/unit_test/list/index.d.ts +13 -0
  41. package/dist/commands/sandbox/unit_test/list/index.js +89 -0
  42. package/dist/commands/sandbox/unit_test/run/index.d.ts +14 -0
  43. package/dist/commands/sandbox/unit_test/run/index.js +77 -0
  44. package/dist/commands/sandbox/unit_test/run_all/index.d.ts +13 -0
  45. package/dist/commands/sandbox/unit_test/run_all/index.js +167 -0
  46. package/dist/commands/sandbox/workflow_test/delete/index.d.ts +17 -0
  47. package/dist/commands/sandbox/workflow_test/delete/index.js +59 -0
  48. package/dist/commands/sandbox/workflow_test/get/index.d.ts +17 -0
  49. package/dist/commands/sandbox/workflow_test/get/index.js +58 -0
  50. package/dist/commands/sandbox/workflow_test/list/index.d.ts +12 -0
  51. package/dist/commands/sandbox/workflow_test/list/index.js +82 -0
  52. package/dist/commands/sandbox/workflow_test/run/index.d.ts +17 -0
  53. package/dist/commands/sandbox/workflow_test/run/index.js +75 -0
  54. package/dist/commands/sandbox/workflow_test/run_all/index.d.ts +12 -0
  55. package/dist/commands/sandbox/workflow_test/run_all/index.js +153 -0
  56. package/dist/commands/tenant/create/index.d.ts +2 -2
  57. package/dist/commands/tenant/create/index.js +23 -11
  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/tenant/unit_test/list/index.d.ts +15 -0
  62. package/dist/commands/tenant/unit_test/list/index.js +140 -0
  63. package/dist/commands/tenant/unit_test/run/index.d.ts +16 -0
  64. package/dist/commands/tenant/unit_test/run/index.js +128 -0
  65. package/dist/commands/tenant/unit_test/run_all/index.d.ts +15 -0
  66. package/dist/commands/tenant/unit_test/run_all/index.js +215 -0
  67. package/dist/commands/tenant/workflow_test/delete/index.d.ts +19 -0
  68. package/dist/commands/tenant/workflow_test/delete/index.js +110 -0
  69. package/dist/commands/tenant/workflow_test/get/index.d.ts +19 -0
  70. package/dist/commands/tenant/workflow_test/get/index.js +112 -0
  71. package/dist/commands/tenant/workflow_test/list/index.d.ts +14 -0
  72. package/dist/commands/tenant/workflow_test/list/index.js +133 -0
  73. package/dist/commands/tenant/workflow_test/run/index.d.ts +19 -0
  74. package/dist/commands/tenant/workflow_test/run/index.js +126 -0
  75. package/dist/commands/tenant/workflow_test/run_all/index.d.ts +14 -0
  76. package/dist/commands/tenant/workflow_test/run_all/index.js +201 -0
  77. package/dist/commands/workspace/edit/index.d.ts +1 -0
  78. package/dist/commands/workspace/edit/index.js +16 -6
  79. package/dist/commands/workspace/get/index.js +9 -7
  80. package/dist/commands/workspace/list/index.d.ts +1 -0
  81. package/dist/commands/workspace/list/index.js +14 -7
  82. package/dist/commands/workspace/push/index.js +30 -2
  83. package/dist/help.d.ts +2 -1
  84. package/dist/help.js +39 -1
  85. package/oclif.manifest.json +4701 -2272
  86. package/package.json +17 -2
@@ -0,0 +1,77 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxUnitTestRun extends BaseCommand {
4
+ static args = {
5
+ unit_test_id: Args.string({
6
+ description: 'ID of the unit test to run',
7
+ required: true,
8
+ }),
9
+ };
10
+ static description = 'Run a unit test for a sandbox environment';
11
+ static examples = [
12
+ `$ xano sandbox unit-test run abc-123
13
+ Running unit test abc-123...
14
+ Result: PASS
15
+ `,
16
+ `$ xano sandbox unit-test run abc-123 -o json`,
17
+ ];
18
+ static flags = {
19
+ ...BaseCommand.baseFlags,
20
+ output: Flags.string({
21
+ char: 'o',
22
+ default: 'summary',
23
+ description: 'Output format',
24
+ options: ['summary', 'json'],
25
+ required: false,
26
+ }),
27
+ };
28
+ async run() {
29
+ const { args, flags } = await this.parse(SandboxUnitTestRun);
30
+ const { profile } = this.resolveProfile(flags);
31
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/unit_test/${encodeURIComponent(args.unit_test_id)}/run`;
32
+ try {
33
+ if (flags.output === 'summary') {
34
+ this.log(`Running unit test ${args.unit_test_id}...`);
35
+ }
36
+ const response = await this.verboseFetch(apiUrl, {
37
+ headers: {
38
+ accept: 'application/json',
39
+ Authorization: `Bearer ${profile.access_token}`,
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ method: 'POST',
43
+ }, flags.verbose, profile.access_token);
44
+ if (!response.ok) {
45
+ const errorText = await response.text();
46
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
47
+ }
48
+ const result = (await response.json());
49
+ if (flags.output === 'json') {
50
+ this.log(JSON.stringify(result, null, 2));
51
+ }
52
+ else {
53
+ if (result.status === 'ok') {
54
+ this.log('Result: PASS');
55
+ }
56
+ else {
57
+ this.log('Result: FAIL');
58
+ const failedExpects = result.results?.filter((r) => r.status === 'fail') ?? [];
59
+ for (const expect of failedExpects) {
60
+ if (expect.message) {
61
+ this.log(` Error: ${expect.message}`);
62
+ }
63
+ }
64
+ this.exit(1);
65
+ }
66
+ }
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error) {
70
+ this.error(`Failed to run unit test: ${error.message}`);
71
+ }
72
+ else {
73
+ this.error(`Failed to run unit test: ${String(error)}`);
74
+ }
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,13 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxUnitTestRunAll extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ 'obj-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,167 @@
1
+ import { Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxUnitTestRunAll extends BaseCommand {
4
+ static description = 'Run all unit tests for a sandbox environment';
5
+ static examples = [
6
+ `$ xano sandbox unit-test run-all
7
+ Running 5 unit tests...
8
+
9
+ PASS my-test [function: math]
10
+ FAIL data-validation [function: validate]
11
+ Error: assertion failed
12
+
13
+ Results: 4 passed, 1 failed
14
+ `,
15
+ `$ xano sandbox unit-test run-all -o json`,
16
+ ];
17
+ static flags = {
18
+ ...BaseCommand.baseFlags,
19
+ branch: Flags.string({
20
+ char: 'b',
21
+ description: 'Filter by branch name',
22
+ required: false,
23
+ }),
24
+ 'obj-type': Flags.string({
25
+ description: 'Filter by object type',
26
+ options: ['function', 'query', 'middleware'],
27
+ required: false,
28
+ }),
29
+ output: Flags.string({
30
+ char: 'o',
31
+ default: 'summary',
32
+ description: 'Output format',
33
+ options: ['summary', 'json'],
34
+ required: false,
35
+ }),
36
+ };
37
+ async run() {
38
+ const { flags } = await this.parse(SandboxUnitTestRunAll);
39
+ const { profile } = this.resolveProfile(flags);
40
+ const baseUrl = `${profile.instance_origin}/api:meta/sandbox/unit_test`;
41
+ try {
42
+ // Step 1: List all unit tests
43
+ const listParams = new URLSearchParams();
44
+ listParams.set('per_page', '10000');
45
+ if (flags.branch)
46
+ listParams.set('branch', flags.branch);
47
+ if (flags['obj-type'])
48
+ listParams.set('obj_type', flags['obj-type']);
49
+ const listResponse = await this.verboseFetch(`${baseUrl}?${listParams}`, {
50
+ headers: {
51
+ accept: 'application/json',
52
+ Authorization: `Bearer ${profile.access_token}`,
53
+ },
54
+ method: 'GET',
55
+ }, flags.verbose, profile.access_token);
56
+ if (!listResponse.ok) {
57
+ const errorText = await listResponse.text();
58
+ this.error(`Failed to list unit tests: ${listResponse.status}: ${listResponse.statusText}\n${errorText}`);
59
+ }
60
+ const data = (await listResponse.json());
61
+ let tests;
62
+ if (Array.isArray(data)) {
63
+ tests = data;
64
+ }
65
+ else if (data && typeof data === 'object' && 'items' in data && Array.isArray(data.items)) {
66
+ tests = data.items;
67
+ }
68
+ else {
69
+ this.error('Unexpected API response format');
70
+ }
71
+ if (tests.length === 0) {
72
+ this.log('No unit tests found');
73
+ return;
74
+ }
75
+ if (flags.output === 'summary') {
76
+ this.log(`Running ${tests.length} unit test${tests.length === 1 ? '' : 's'}...\n`);
77
+ }
78
+ // Step 2: Run each test
79
+ const results = [];
80
+ for (const test of tests) {
81
+ const runUrl = `${baseUrl}/${test.id}/run`;
82
+ try {
83
+ const runResponse = await this.verboseFetch(runUrl, {
84
+ headers: {
85
+ accept: 'application/json',
86
+ Authorization: `Bearer ${profile.access_token}`,
87
+ 'Content-Type': 'application/json',
88
+ },
89
+ method: 'POST',
90
+ }, flags.verbose, profile.access_token);
91
+ if (!runResponse.ok) {
92
+ const errorText = await runResponse.text();
93
+ results.push({
94
+ message: `API error ${runResponse.status}: ${errorText}`,
95
+ name: test.name,
96
+ obj_name: test.obj_name,
97
+ obj_type: test.obj_type,
98
+ status: 'fail',
99
+ });
100
+ if (flags.output === 'summary') {
101
+ this.log(`FAIL ${test.name} [${test.obj_type}: ${test.obj_name}]`);
102
+ this.log(` Error: API error ${runResponse.status}`);
103
+ }
104
+ continue;
105
+ }
106
+ const runResult = (await runResponse.json());
107
+ const passed = runResult.status === 'ok';
108
+ const failedExpects = runResult.results?.filter((r) => r.status === 'fail') ?? [];
109
+ results.push({
110
+ message: failedExpects[0]?.message,
111
+ name: test.name,
112
+ obj_name: test.obj_name,
113
+ obj_type: test.obj_type,
114
+ status: passed ? 'pass' : 'fail',
115
+ });
116
+ if (flags.output === 'summary') {
117
+ if (passed) {
118
+ this.log(`PASS ${test.name} [${test.obj_type}: ${test.obj_name}]`);
119
+ }
120
+ else {
121
+ this.log(`FAIL ${test.name} [${test.obj_type}: ${test.obj_name}]`);
122
+ for (const expect of failedExpects) {
123
+ if (expect.message) {
124
+ this.log(` Error: ${expect.message}`);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ catch (error) {
131
+ const message = error instanceof Error ? error.message : String(error);
132
+ results.push({
133
+ message,
134
+ name: test.name,
135
+ obj_name: test.obj_name,
136
+ obj_type: test.obj_type,
137
+ status: 'fail',
138
+ });
139
+ if (flags.output === 'summary') {
140
+ this.log(`FAIL ${test.name} [${test.obj_type}: ${test.obj_name}]`);
141
+ this.log(` Error: ${message}`);
142
+ }
143
+ }
144
+ }
145
+ // Step 3: Summary
146
+ const passed = results.filter((r) => r.status === 'pass').length;
147
+ const failed = results.filter((r) => r.status === 'fail').length;
148
+ if (flags.output === 'json') {
149
+ this.log(JSON.stringify({ failed, passed, results }, null, 2));
150
+ }
151
+ else {
152
+ this.log(`\nResults: ${passed} passed, ${failed} failed`);
153
+ }
154
+ if (failed > 0) {
155
+ process.exitCode = 1;
156
+ }
157
+ }
158
+ catch (error) {
159
+ if (error instanceof Error) {
160
+ this.error(`Failed to run unit tests: ${error.message}`);
161
+ }
162
+ else {
163
+ this.error(`Failed to run unit tests: ${String(error)}`);
164
+ }
165
+ }
166
+ }
167
+ }
@@ -0,0 +1,17 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxWorkflowTestDelete extends BaseCommand {
3
+ static args: {
4
+ workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
+ max?: number;
6
+ min?: number;
7
+ }>;
8
+ };
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
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
+ }
@@ -0,0 +1,59 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxWorkflowTestDelete extends BaseCommand {
4
+ static args = {
5
+ workflow_test_id: Args.integer({
6
+ description: 'ID of the workflow test to delete',
7
+ required: true,
8
+ }),
9
+ };
10
+ static description = 'Delete a workflow test for a sandbox environment';
11
+ static examples = [
12
+ `$ xano sandbox workflow-test delete 42
13
+ Deleted workflow test 42
14
+ `,
15
+ `$ xano sandbox workflow-test delete 42 -o 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 { 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}`;
31
+ try {
32
+ const response = await this.verboseFetch(apiUrl, {
33
+ headers: {
34
+ accept: 'application/json',
35
+ Authorization: `Bearer ${profile.access_token}`,
36
+ },
37
+ method: 'DELETE',
38
+ }, flags.verbose, profile.access_token);
39
+ if (!response.ok) {
40
+ const errorText = await response.text();
41
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
42
+ }
43
+ if (flags.output === 'json') {
44
+ this.log(JSON.stringify({ deleted: true, workflow_test_id: args.workflow_test_id }, null, 2));
45
+ }
46
+ else {
47
+ this.log(`Deleted workflow test ${args.workflow_test_id}`);
48
+ }
49
+ }
50
+ catch (error) {
51
+ if (error instanceof Error) {
52
+ this.error(`Failed to delete workflow test: ${error.message}`);
53
+ }
54
+ else {
55
+ this.error(`Failed to delete workflow test: ${String(error)}`);
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,17 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxWorkflowTestGet extends BaseCommand {
3
+ static args: {
4
+ workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
+ max?: number;
6
+ min?: number;
7
+ }>;
8
+ };
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
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
+ }
@@ -0,0 +1,58 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxWorkflowTestGet extends BaseCommand {
4
+ static args = {
5
+ workflow_test_id: Args.integer({
6
+ description: 'ID of the workflow test',
7
+ required: true,
8
+ }),
9
+ };
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`];
12
+ static flags = {
13
+ ...BaseCommand.baseFlags,
14
+ output: Flags.string({
15
+ char: 'o',
16
+ default: 'summary',
17
+ description: 'Output format',
18
+ options: ['summary', 'json'],
19
+ required: false,
20
+ }),
21
+ };
22
+ async run() {
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}`;
26
+ try {
27
+ const response = await this.verboseFetch(apiUrl, {
28
+ headers: {
29
+ accept: 'application/json',
30
+ Authorization: `Bearer ${profile.access_token}`,
31
+ },
32
+ method: 'GET',
33
+ }, flags.verbose, profile.access_token);
34
+ if (!response.ok) {
35
+ const errorText = await response.text();
36
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
37
+ }
38
+ const test = await response.json();
39
+ if (flags.output === 'json') {
40
+ this.log(JSON.stringify(test, null, 2));
41
+ }
42
+ else {
43
+ const t = test;
44
+ this.log(`Workflow Test: ${t.name} (ID: ${t.id})`);
45
+ if (t.description)
46
+ this.log(` Description: ${t.description}`);
47
+ }
48
+ }
49
+ catch (error) {
50
+ if (error instanceof Error) {
51
+ this.error(`Failed to get workflow test: ${error.message}`);
52
+ }
53
+ else {
54
+ this.error(`Failed to get workflow test: ${String(error)}`);
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,12 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxWorkflowTestList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,82 @@
1
+ import { Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxWorkflowTestList extends BaseCommand {
4
+ static description = 'List workflow tests for a sandbox environment';
5
+ static examples = [
6
+ `$ xano sandbox workflow-test list
7
+ Workflow tests:
8
+ - my-test (ID: 1)
9
+ `,
10
+ `$ xano sandbox workflow-test list -o json`,
11
+ ];
12
+ static flags = {
13
+ ...BaseCommand.baseFlags,
14
+ branch: Flags.string({
15
+ char: 'b',
16
+ description: 'Filter by branch name',
17
+ required: false,
18
+ }),
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(SandboxWorkflowTestList);
29
+ const { profile } = this.resolveProfile(flags);
30
+ const params = new URLSearchParams();
31
+ params.set('per_page', '10000');
32
+ if (flags.branch)
33
+ params.set('branch', flags.branch);
34
+ const apiUrl = `${profile.instance_origin}/api:meta/sandbox/workflow_test?${params}`;
35
+ try {
36
+ const response = await this.verboseFetch(apiUrl, {
37
+ headers: {
38
+ accept: 'application/json',
39
+ Authorization: `Bearer ${profile.access_token}`,
40
+ },
41
+ method: 'GET',
42
+ }, flags.verbose, profile.access_token);
43
+ if (!response.ok) {
44
+ const errorText = await response.text();
45
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
46
+ }
47
+ const data = (await response.json());
48
+ let tests;
49
+ if (Array.isArray(data)) {
50
+ tests = data;
51
+ }
52
+ else if (data && typeof data === 'object' && 'items' in data && Array.isArray(data.items)) {
53
+ tests = data.items;
54
+ }
55
+ else {
56
+ this.error('Unexpected API response format');
57
+ }
58
+ if (flags.output === 'json') {
59
+ this.log(JSON.stringify(tests, null, 2));
60
+ }
61
+ else {
62
+ if (tests.length === 0) {
63
+ this.log('No workflow tests found');
64
+ }
65
+ else {
66
+ this.log(`Workflow tests for sandbox environment:`);
67
+ for (const test of tests) {
68
+ this.log(` - ${test.name} (ID: ${test.id})`);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ catch (error) {
74
+ if (error instanceof Error) {
75
+ this.error(`Failed to list workflow tests: ${error.message}`);
76
+ }
77
+ else {
78
+ this.error(`Failed to list workflow tests: ${String(error)}`);
79
+ }
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,17 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxWorkflowTestRun extends BaseCommand {
3
+ static args: {
4
+ workflow_test_id: import("@oclif/core/interfaces").Arg<number, {
5
+ max?: number;
6
+ min?: number;
7
+ }>;
8
+ };
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
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
+ }
@@ -0,0 +1,75 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import BaseCommand from '../../../../base-command.js';
3
+ export default class SandboxWorkflowTestRun extends BaseCommand {
4
+ static args = {
5
+ workflow_test_id: Args.integer({
6
+ description: 'ID of the workflow test to run',
7
+ required: true,
8
+ }),
9
+ };
10
+ static description = 'Run a workflow test for a sandbox environment';
11
+ static examples = [
12
+ `$ xano sandbox workflow-test run 42
13
+ Running workflow test 42...
14
+ Result: PASS (0.25s)
15
+ `,
16
+ `$ xano sandbox workflow-test run 42 -o json`,
17
+ ];
18
+ static flags = {
19
+ ...BaseCommand.baseFlags,
20
+ output: Flags.string({
21
+ char: 'o',
22
+ default: 'summary',
23
+ description: 'Output format',
24
+ options: ['summary', 'json'],
25
+ required: false,
26
+ }),
27
+ };
28
+ async 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`;
32
+ try {
33
+ if (flags.output === 'summary') {
34
+ this.log(`Running workflow test ${args.workflow_test_id}...`);
35
+ }
36
+ const response = await this.verboseFetch(apiUrl, {
37
+ headers: {
38
+ accept: 'application/json',
39
+ Authorization: `Bearer ${profile.access_token}`,
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ method: 'POST',
43
+ }, flags.verbose, profile.access_token);
44
+ if (!response.ok) {
45
+ const errorText = await response.text();
46
+ this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
47
+ }
48
+ const result = (await response.json());
49
+ if (flags.output === 'json') {
50
+ this.log(JSON.stringify(result, null, 2));
51
+ }
52
+ else {
53
+ const timing = result.timing ? ` (${result.timing}s)` : '';
54
+ if (result.status === 'ok') {
55
+ this.log(`Result: PASS${timing}`);
56
+ }
57
+ else {
58
+ this.log(`Result: FAIL${timing}`);
59
+ if (result.message) {
60
+ this.log(` Error: ${result.message}`);
61
+ }
62
+ this.exit(1);
63
+ }
64
+ }
65
+ }
66
+ catch (error) {
67
+ if (error instanceof Error) {
68
+ this.error(`Failed to run workflow test: ${error.message}`);
69
+ }
70
+ else {
71
+ this.error(`Failed to run workflow test: ${String(error)}`);
72
+ }
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,12 @@
1
+ import BaseCommand from '../../../../base-command.js';
2
+ export default class SandboxWorkflowTestRunAll extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }