@xano/cli 0.0.95-beta.1 → 0.0.95-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -8
- package/dist/base-command.d.ts +24 -0
- package/dist/base-command.js +37 -0
- package/dist/commands/release/deploy/index.d.ts +17 -0
- package/dist/commands/release/deploy/index.js +107 -0
- package/dist/commands/{ephemeral → sandbox}/env/delete/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/delete/index.js +17 -33
- package/dist/commands/{ephemeral → sandbox}/env/get/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/get/index.js +13 -29
- package/dist/commands/{ephemeral → sandbox}/env/get_all/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/get_all/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/env/list/index.d.ts +1 -4
- package/dist/commands/sandbox/env/list/index.js +67 -0
- package/dist/commands/{ephemeral → sandbox}/env/set/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/set/index.js +14 -30
- package/dist/commands/{ephemeral → sandbox}/env/set_all/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/env/set_all/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/get/index.d.ts +1 -4
- package/dist/commands/sandbox/get/index.js +48 -0
- package/dist/commands/sandbox/impersonate/index.d.ts +5 -0
- package/dist/commands/sandbox/impersonate/index.js +5 -0
- package/dist/commands/{ephemeral → sandbox}/license/get/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/license/get/index.js +16 -32
- package/dist/commands/{ephemeral → sandbox}/license/set/index.d.ts +1 -4
- package/dist/commands/{ephemeral → sandbox}/license/set/index.js +17 -33
- package/dist/commands/{ephemeral → sandbox}/pull/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/pull/index.js +11 -26
- package/dist/commands/{ephemeral → sandbox}/push/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/push/index.js +13 -28
- package/dist/commands/{ephemeral/delete → sandbox/reset}/index.d.ts +1 -5
- package/dist/commands/sandbox/reset/index.js +71 -0
- package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.d.ts +1 -4
- package/dist/commands/{ephemeral/impersonate → sandbox/review}/index.js +15 -31
- package/dist/commands/{ephemeral/unit_test/run_all → sandbox/unit_test/list}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/list/index.js +10 -24
- package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/run/index.js +9 -23
- package/dist/commands/{ephemeral/unit_test/list → sandbox/unit_test/run_all}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/unit_test/run_all/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/get → sandbox/workflow_test/delete}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/delete/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/run → sandbox/workflow_test/get}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/get/index.js +8 -25
- package/dist/commands/{ephemeral/workflow_test/run_all → sandbox/workflow_test/list}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/list/index.js +11 -25
- package/dist/commands/{ephemeral/workflow_test/delete → sandbox/workflow_test/run}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/run/index.js +9 -23
- package/dist/commands/{ephemeral/workflow_test/list → sandbox/workflow_test/run_all}/index.d.ts +1 -2
- package/dist/commands/{ephemeral → sandbox}/workflow_test/run_all/index.js +9 -23
- package/dist/commands/tenant/get/index.js +2 -2
- package/dist/commands/tenant/list/index.js +2 -2
- package/dist/commands/tenant/push/index.js +0 -34
- package/dist/commands/workspace/push/index.js +26 -0
- package/oclif.manifest.json +2266 -2658
- package/package.json +7 -7
- package/dist/commands/ephemeral/access/index.d.ts +0 -15
- package/dist/commands/ephemeral/access/index.js +0 -78
- package/dist/commands/ephemeral/create/index.d.ts +0 -17
- package/dist/commands/ephemeral/create/index.js +0 -102
- package/dist/commands/ephemeral/delete/index.js +0 -99
- package/dist/commands/ephemeral/env/list/index.js +0 -83
- package/dist/commands/ephemeral/get/index.js +0 -102
- package/dist/commands/ephemeral/list/index.d.ts +0 -15
- package/dist/commands/ephemeral/list/index.js +0 -109
- package/dist/commands/ephemeral/shared/index.d.ts +0 -15
- package/dist/commands/ephemeral/shared/index.js +0 -108
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import BaseCommand from '../../../../base-command.js';
|
|
3
|
-
export default class
|
|
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
|
|
10
|
+
static description = 'Run a workflow test for a sandbox environment';
|
|
11
11
|
static examples = [
|
|
12
|
-
`$ xano
|
|
12
|
+
`$ xano sandbox workflow-test run 42
|
|
13
13
|
Running workflow test 42...
|
|
14
14
|
Result: PASS (0.25s)
|
|
15
15
|
`,
|
|
16
|
-
`$ xano
|
|
16
|
+
`$ xano sandbox workflow-test run 42 -o json`,
|
|
17
17
|
];
|
|
18
18
|
static flags = {
|
|
19
19
|
...BaseCommand.baseFlags,
|
|
@@ -24,27 +24,13 @@ 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(
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
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 tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
32
|
+
const tenantName = tenant.name;
|
|
33
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${encodeURIComponent(tenantName)}/workflow_test/${args.workflow_test_id}/run`;
|
|
48
34
|
try {
|
|
49
35
|
if (flags.output === 'summary') {
|
|
50
36
|
this.log(`Running workflow test ${args.workflow_test_id}...`);
|
package/dist/commands/{ephemeral/workflow_test/list → sandbox/workflow_test/run_all}/index.d.ts
RENAMED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
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
|
|
4
|
-
static description = 'Run all workflow tests for
|
|
3
|
+
export default class SandboxWorkflowTestRunAll extends BaseCommand {
|
|
4
|
+
static description = 'Run all workflow tests for a sandbox environment';
|
|
5
5
|
static examples = [
|
|
6
|
-
`$ xano
|
|
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
|
|
15
|
+
`$ xano sandbox workflow-test run-all -o json`,
|
|
16
16
|
];
|
|
17
17
|
static flags = {
|
|
18
18
|
...BaseCommand.baseFlags,
|
|
@@ -28,27 +28,13 @@ 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(
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
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 tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
36
|
+
const tenantName = tenant.name;
|
|
37
|
+
const baseUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${encodeURIComponent(tenantName)}/workflow_test`;
|
|
52
38
|
try {
|
|
53
39
|
// Step 1: List all workflow tests
|
|
54
40
|
const listParams = new URLSearchParams();
|
|
@@ -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.
|
|
103
|
-
this.log(`
|
|
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
|
|
96
|
-
this.log(` - ${tenant.display || tenant.name} (${tenant.name})${state}${license}${
|
|
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)) {
|
|
@@ -282,6 +282,24 @@ Push functions but exclude test files
|
|
|
282
282
|
}
|
|
283
283
|
else {
|
|
284
284
|
const errorText = await dryRunResponse.text();
|
|
285
|
+
// Check if push is disabled on this workspace
|
|
286
|
+
try {
|
|
287
|
+
const errorJson = JSON.parse(errorText);
|
|
288
|
+
if (errorJson.message?.includes('Push is disabled')) {
|
|
289
|
+
this.log('');
|
|
290
|
+
this.log(ux.colorize('red', ux.colorize('bold', 'Direct push to this workspace is disabled.')));
|
|
291
|
+
this.log(ux.colorize('dim', 'To apply changes to the workspace, use the sandbox review flow:'));
|
|
292
|
+
this.log(` ${ux.colorize('cyan', 'xano sandbox push')} ${ux.colorize('dim', '— push changes to your sandbox')}`);
|
|
293
|
+
this.log(` ${ux.colorize('cyan', 'xano sandbox review')} ${ux.colorize('dim', '— edit any logic, inspect the snapshot diff, and promote changes to the workspace')}`);
|
|
294
|
+
this.log('');
|
|
295
|
+
this.log(ux.colorize('dim', 'To enable direct push, go to Workspace Settings → CLI → Allow Direct Workspace Push.'));
|
|
296
|
+
this.log('');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// Not JSON, fall through
|
|
302
|
+
}
|
|
285
303
|
this.warn(`Push preview failed (${dryRunResponse.status}). Skipping preview.`);
|
|
286
304
|
if (flags.verbose) {
|
|
287
305
|
this.log(ux.colorize('dim', errorText));
|
|
@@ -465,6 +483,14 @@ Push functions but exclude test files
|
|
|
465
483
|
if (errorJson.payload?.param) {
|
|
466
484
|
errorMessage += `\n Parameter: ${errorJson.payload.param}`;
|
|
467
485
|
}
|
|
486
|
+
// Provide clear guidance when push is disabled
|
|
487
|
+
if (errorJson.message?.includes('Push is disabled')) {
|
|
488
|
+
this.error(`Push is disabled for this workspace.\n\n` +
|
|
489
|
+
`To enable, go to Workspace Settings and turn on "Allow Push".\n\n` +
|
|
490
|
+
`Alternatively, use sandbox commands:\n` +
|
|
491
|
+
` xano sandbox push ${args.directory}\n` +
|
|
492
|
+
` xano sandbox impersonate`);
|
|
493
|
+
}
|
|
468
494
|
}
|
|
469
495
|
catch {
|
|
470
496
|
errorMessage += `\n${errorText}`;
|