@xano/cli 0.0.95-beta.3 → 0.0.95
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 +2 -27
- package/dist/base-command.d.ts +0 -24
- package/dist/base-command.js +0 -37
- package/dist/commands/tenant/create/index.d.ts +3 -1
- package/dist/commands/tenant/create/index.js +28 -6
- 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 +34 -0
- package/dist/commands/workspace/push/index.js +0 -26
- package/dist/help.d.ts +1 -2
- package/dist/help.js +1 -39
- package/oclif.manifest.json +2059 -4455
- package/package.json +1 -16
- package/dist/commands/release/deploy/index.d.ts +0 -17
- package/dist/commands/release/deploy/index.js +0 -107
- package/dist/commands/sandbox/env/delete/index.d.ts +0 -14
- package/dist/commands/sandbox/env/delete/index.js +0 -89
- package/dist/commands/sandbox/env/get/index.d.ts +0 -12
- package/dist/commands/sandbox/env/get/index.js +0 -65
- package/dist/commands/sandbox/env/get_all/index.d.ts +0 -13
- package/dist/commands/sandbox/env/get_all/index.js +0 -78
- package/dist/commands/sandbox/env/list/index.d.ts +0 -11
- package/dist/commands/sandbox/env/list/index.js +0 -67
- package/dist/commands/sandbox/env/set/index.d.ts +0 -13
- package/dist/commands/sandbox/env/set/index.js +0 -74
- package/dist/commands/sandbox/env/set_all/index.d.ts +0 -13
- package/dist/commands/sandbox/env/set_all/index.js +0 -86
- package/dist/commands/sandbox/get/index.d.ts +0 -11
- package/dist/commands/sandbox/get/index.js +0 -48
- package/dist/commands/sandbox/impersonate/index.d.ts +0 -5
- package/dist/commands/sandbox/impersonate/index.js +0 -5
- package/dist/commands/sandbox/license/get/index.d.ts +0 -13
- package/dist/commands/sandbox/license/get/index.js +0 -78
- package/dist/commands/sandbox/license/set/index.d.ts +0 -14
- package/dist/commands/sandbox/license/set/index.js +0 -95
- package/dist/commands/sandbox/pull/index.d.ts +0 -17
- package/dist/commands/sandbox/pull/index.js +0 -182
- package/dist/commands/sandbox/push/index.d.ts +0 -18
- package/dist/commands/sandbox/push/index.js +0 -143
- package/dist/commands/sandbox/reset/index.d.ts +0 -12
- package/dist/commands/sandbox/reset/index.js +0 -71
- package/dist/commands/sandbox/review/index.d.ts +0 -13
- package/dist/commands/sandbox/review/index.js +0 -94
- package/dist/commands/sandbox/unit_test/list/index.d.ts +0 -13
- package/dist/commands/sandbox/unit_test/list/index.js +0 -91
- package/dist/commands/sandbox/unit_test/run/index.d.ts +0 -14
- package/dist/commands/sandbox/unit_test/run/index.js +0 -79
- package/dist/commands/sandbox/unit_test/run_all/index.d.ts +0 -13
- package/dist/commands/sandbox/unit_test/run_all/index.js +0 -169
- package/dist/commands/sandbox/workflow_test/delete/index.d.ts +0 -17
- package/dist/commands/sandbox/workflow_test/delete/index.js +0 -61
- package/dist/commands/sandbox/workflow_test/get/index.d.ts +0 -17
- package/dist/commands/sandbox/workflow_test/get/index.js +0 -60
- package/dist/commands/sandbox/workflow_test/list/index.d.ts +0 -12
- package/dist/commands/sandbox/workflow_test/list/index.js +0 -84
- package/dist/commands/sandbox/workflow_test/run/index.d.ts +0 -17
- package/dist/commands/sandbox/workflow_test/run/index.js +0 -77
- package/dist/commands/sandbox/workflow_test/run_all/index.d.ts +0 -12
- package/dist/commands/sandbox/workflow_test/run_all/index.js +0 -155
- package/dist/commands/tenant/unit_test/list/index.d.ts +0 -15
- package/dist/commands/tenant/unit_test/list/index.js +0 -140
- package/dist/commands/tenant/unit_test/run/index.d.ts +0 -16
- package/dist/commands/tenant/unit_test/run/index.js +0 -128
- package/dist/commands/tenant/unit_test/run_all/index.d.ts +0 -15
- package/dist/commands/tenant/unit_test/run_all/index.js +0 -215
- package/dist/commands/tenant/workflow_test/delete/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/delete/index.js +0 -110
- package/dist/commands/tenant/workflow_test/get/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/get/index.js +0 -112
- package/dist/commands/tenant/workflow_test/list/index.d.ts +0 -14
- package/dist/commands/tenant/workflow_test/list/index.js +0 -133
- package/dist/commands/tenant/workflow_test/run/index.d.ts +0 -19
- package/dist/commands/tenant/workflow_test/run/index.js +0 -126
- package/dist/commands/tenant/workflow_test/run_all/index.d.ts +0 -14
- package/dist/commands/tenant/workflow_test/run_all/index.js +0 -201
package/README.md
CHANGED
|
@@ -235,11 +235,6 @@ xano release pull ./my-release -r v1.0 --env --records
|
|
|
235
235
|
xano release push ./my-release -n "v2.0"
|
|
236
236
|
xano release push ./my-release -n "v2.0" --hotfix -d "Critical fix"
|
|
237
237
|
xano release push ./my-release -n "v2.0" --no-records --no-env
|
|
238
|
-
|
|
239
|
-
# Deploy a release to its workspace as a new branch
|
|
240
|
-
xano release deploy "v1.0"
|
|
241
|
-
xano release deploy "v1.0" --branch "restore-v1" --no-set_live
|
|
242
|
-
xano release deploy "v1.0" -w 40 -o json
|
|
243
238
|
```
|
|
244
239
|
|
|
245
240
|
### Platforms
|
|
@@ -307,7 +302,8 @@ xano tenant get <tenant_name>
|
|
|
307
302
|
|
|
308
303
|
# Create a tenant
|
|
309
304
|
xano tenant create "My Tenant"
|
|
310
|
-
xano tenant create "My Tenant" -d "Description" --cluster_id 1 --platform_id 5
|
|
305
|
+
xano tenant create "My Tenant" -d "Description" --type tier2 --cluster_id 1 --platform_id 5
|
|
306
|
+
xano tenant create "My Tenant" --type tier2 --cluster_id 1 --license ./license.yaml
|
|
311
307
|
|
|
312
308
|
# Edit a tenant
|
|
313
309
|
xano tenant edit <tenant_name> --display "New Name" -d "New description"
|
|
@@ -445,27 +441,6 @@ xano tenant cluster license set <cluster_id>
|
|
|
445
441
|
xano tenant cluster license set <cluster_id> --file ./kubeconfig.yaml
|
|
446
442
|
```
|
|
447
443
|
|
|
448
|
-
### Sandbox
|
|
449
|
-
|
|
450
|
-
Manage your sandbox tenant. Each user has a single sandbox tenant that is auto-provisioned on first use.
|
|
451
|
-
|
|
452
|
-
```bash
|
|
453
|
-
# Get your sandbox tenant (creates if needed)
|
|
454
|
-
xano sandbox get
|
|
455
|
-
xano sandbox get -o json
|
|
456
|
-
|
|
457
|
-
# Push/pull workspace data
|
|
458
|
-
xano sandbox push ./my-workspace
|
|
459
|
-
xano sandbox pull ./my-tenant
|
|
460
|
-
|
|
461
|
-
# Impersonate (open in browser)
|
|
462
|
-
xano sandbox impersonate
|
|
463
|
-
|
|
464
|
-
# Reset all workspace data
|
|
465
|
-
xano sandbox reset
|
|
466
|
-
xano sandbox reset --force
|
|
467
|
-
```
|
|
468
|
-
|
|
469
444
|
### Static Hosts
|
|
470
445
|
|
|
471
446
|
```bash
|
package/dist/base-command.d.ts
CHANGED
|
@@ -14,16 +14,6 @@ export interface CredentialsFile {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
export declare function buildUserAgent(version: string): string;
|
|
17
|
-
export interface SandboxTenant {
|
|
18
|
-
created_at?: string;
|
|
19
|
-
description?: string;
|
|
20
|
-
display?: string;
|
|
21
|
-
ephemeral?: boolean;
|
|
22
|
-
id: number;
|
|
23
|
-
name: string;
|
|
24
|
-
state?: string;
|
|
25
|
-
xano_domain?: string;
|
|
26
|
-
}
|
|
27
17
|
export default abstract class BaseCommand extends Command {
|
|
28
18
|
static baseFlags: {
|
|
29
19
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -48,20 +38,6 @@ export default abstract class BaseCommand extends Command {
|
|
|
48
38
|
* Load and parse the credentials file. Returns null if the file doesn't exist.
|
|
49
39
|
*/
|
|
50
40
|
protected loadCredentialsFile(): CredentialsFile | null;
|
|
51
|
-
/**
|
|
52
|
-
* Get or create the singleton sandbox environment for the authenticated user.
|
|
53
|
-
* Returns the sandbox object (existing or newly created).
|
|
54
|
-
*/
|
|
55
|
-
protected getOrCreateSandbox(profile: ProfileConfig, verbose: boolean): Promise<SandboxTenant>;
|
|
56
|
-
/**
|
|
57
|
-
* Resolve profile from flags, validating instance_origin and access_token exist.
|
|
58
|
-
*/
|
|
59
|
-
protected resolveProfile(flags: {
|
|
60
|
-
profile?: string;
|
|
61
|
-
}): {
|
|
62
|
-
profile: ProfileConfig;
|
|
63
|
-
profileName: string;
|
|
64
|
-
};
|
|
65
41
|
/**
|
|
66
42
|
* Make an HTTP request with optional verbose logging.
|
|
67
43
|
* Use this for all Metadata API calls to support the --verbose flag.
|
package/dist/base-command.js
CHANGED
|
@@ -103,43 +103,6 @@ export default class BaseCommand extends Command {
|
|
|
103
103
|
}
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
106
|
-
/**
|
|
107
|
-
* Get or create the singleton sandbox environment for the authenticated user.
|
|
108
|
-
* Returns the sandbox object (existing or newly created).
|
|
109
|
-
*/
|
|
110
|
-
async getOrCreateSandbox(profile, verbose) {
|
|
111
|
-
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/me`;
|
|
112
|
-
const response = await this.verboseFetch(apiUrl, {
|
|
113
|
-
headers: {
|
|
114
|
-
accept: 'application/json',
|
|
115
|
-
Authorization: `Bearer ${profile.access_token}`,
|
|
116
|
-
},
|
|
117
|
-
method: 'GET',
|
|
118
|
-
}, verbose, profile.access_token);
|
|
119
|
-
if (!response.ok) {
|
|
120
|
-
const errorText = await response.text();
|
|
121
|
-
this.error(`Failed to get sandbox environment: ${response.status} ${response.statusText}\n${errorText}`);
|
|
122
|
-
}
|
|
123
|
-
return (await response.json());
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Resolve profile from flags, validating instance_origin and access_token exist.
|
|
127
|
-
*/
|
|
128
|
-
resolveProfile(flags) {
|
|
129
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
130
|
-
const credentials = this.loadCredentialsFile();
|
|
131
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
132
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
133
|
-
}
|
|
134
|
-
const profile = credentials.profiles[profileName];
|
|
135
|
-
if (!profile.instance_origin) {
|
|
136
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
137
|
-
}
|
|
138
|
-
if (!profile.access_token) {
|
|
139
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
140
|
-
}
|
|
141
|
-
return { profile, profileName };
|
|
142
|
-
}
|
|
143
106
|
/**
|
|
144
107
|
* Make an HTTP request with optional verbose logging.
|
|
145
108
|
* Use this for all Metadata API calls to support the --verbose flag.
|
|
@@ -9,10 +9,12 @@ export default class TenantCreate extends BaseCommand {
|
|
|
9
9
|
cluster_id: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
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
|
+
ephemeral: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
13
|
ingress: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
license: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
license: 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>;
|
|
15
16
|
platform_id: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
18
|
tasks: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
19
|
workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
20
|
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 --
|
|
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,
|
|
@@ -33,15 +34,18 @@ Created tenant: Production (production) - ID: 42
|
|
|
33
34
|
description: 'Custom domain for the tenant',
|
|
34
35
|
required: false,
|
|
35
36
|
}),
|
|
37
|
+
ephemeral: Flags.boolean({
|
|
38
|
+
default: false,
|
|
39
|
+
description: 'Mark tenant as ephemeral (allows push operations)',
|
|
40
|
+
}),
|
|
36
41
|
ingress: Flags.boolean({
|
|
37
42
|
allowNo: true,
|
|
38
43
|
default: true,
|
|
39
44
|
description: 'Enable ingress',
|
|
40
45
|
}),
|
|
41
46
|
license: Flags.string({
|
|
42
|
-
|
|
43
|
-
description: '
|
|
44
|
-
options: ['tier1', 'tier2', 'tier3'],
|
|
47
|
+
char: 'l',
|
|
48
|
+
description: 'Path to a license override file to apply during creation',
|
|
45
49
|
required: false,
|
|
46
50
|
}),
|
|
47
51
|
output: Flags.string({
|
|
@@ -55,6 +59,12 @@ Created tenant: Production (production) - ID: 42
|
|
|
55
59
|
description: 'Platform ID to use',
|
|
56
60
|
required: false,
|
|
57
61
|
}),
|
|
62
|
+
type: Flags.string({
|
|
63
|
+
default: 'tier1',
|
|
64
|
+
description: 'Tenant type',
|
|
65
|
+
options: ['tier1', 'tier2', 'tier3'],
|
|
66
|
+
required: false,
|
|
67
|
+
}),
|
|
58
68
|
tasks: Flags.boolean({
|
|
59
69
|
allowNo: true,
|
|
60
70
|
default: true,
|
|
@@ -87,8 +97,9 @@ Created tenant: Production (production) - ID: 42
|
|
|
87
97
|
}
|
|
88
98
|
const body = {
|
|
89
99
|
display: args.display,
|
|
100
|
+
ephemeral: flags.ephemeral,
|
|
90
101
|
ingress: flags.ingress,
|
|
91
|
-
license: flags.
|
|
102
|
+
license: flags.type,
|
|
92
103
|
tag: [],
|
|
93
104
|
tasks: flags.tasks,
|
|
94
105
|
};
|
|
@@ -102,7 +113,16 @@ Created tenant: Production (production) - ID: 42
|
|
|
102
113
|
body.platform_id = flags.platform_id;
|
|
103
114
|
if (flags.domain)
|
|
104
115
|
body.domain = flags.domain;
|
|
105
|
-
if (flags.license
|
|
116
|
+
if (flags.license) {
|
|
117
|
+
const licensePath = path.resolve(flags.license);
|
|
118
|
+
if (!fs.existsSync(licensePath)) {
|
|
119
|
+
this.error(`License file not found: ${licensePath}`);
|
|
120
|
+
}
|
|
121
|
+
const licenseContent = fs.readFileSync(licensePath, 'utf8');
|
|
122
|
+
body.license_overrides = yaml.load(licenseContent);
|
|
123
|
+
}
|
|
124
|
+
const effectiveType = flags.cluster_id ? 'tier3' : flags.type;
|
|
125
|
+
if (effectiveType === 'tier2' || effectiveType === 'tier3') {
|
|
106
126
|
this.warn('This may take a few minutes. Please be patient.');
|
|
107
127
|
}
|
|
108
128
|
const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant`;
|
|
@@ -129,6 +149,8 @@ Created tenant: Production (production) - ID: 42
|
|
|
129
149
|
if (tenant.state) {
|
|
130
150
|
this.log(` State: ${tenant.state}`);
|
|
131
151
|
}
|
|
152
|
+
if (flags.license)
|
|
153
|
+
this.log(` License: applied`);
|
|
132
154
|
}
|
|
133
155
|
}
|
|
134
156
|
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.
|
|
103
|
-
this.log(`
|
|
102
|
+
if (tenant.ephemeral)
|
|
103
|
+
this.log(` Ephemeral: ${tenant.ephemeral}`);
|
|
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 ephemeral = tenant.ephemeral ? ' [ephemeral]' : '';
|
|
96
|
+
this.log(` - ${tenant.display || tenant.name} (${tenant.name})${state}${license}${ephemeral}`);
|
|
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,6 +100,40 @@ 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 tenant create "name" --ephemeral`);
|
|
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
|
+
}
|
|
103
137
|
// Resolve the input directory
|
|
104
138
|
const inputDir = path.resolve(args.directory);
|
|
105
139
|
if (!fs.existsSync(inputDir)) {
|
|
@@ -282,24 +282,6 @@ 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
|
-
}
|
|
303
285
|
this.warn(`Push preview failed (${dryRunResponse.status}). Skipping preview.`);
|
|
304
286
|
if (flags.verbose) {
|
|
305
287
|
this.log(ux.colorize('dim', errorText));
|
|
@@ -483,14 +465,6 @@ Push functions but exclude test files
|
|
|
483
465
|
if (errorJson.payload?.param) {
|
|
484
466
|
errorMessage += `\n Parameter: ${errorJson.payload.param}`;
|
|
485
467
|
}
|
|
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
|
-
}
|
|
494
468
|
}
|
|
495
469
|
catch {
|
|
496
470
|
errorMessage += `\n${errorText}`;
|
package/dist/help.d.ts
CHANGED
|
@@ -12,10 +12,9 @@ declare class CustomCommandHelp extends BaseCommandHelp {
|
|
|
12
12
|
protected flagHelpLabel(flag: Command.Flag.Any, showOptions?: boolean): string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Custom Help class that
|
|
15
|
+
* Custom Help class that uses CustomCommandHelp
|
|
16
16
|
*/
|
|
17
17
|
export default class Help extends BaseHelp {
|
|
18
18
|
protected CommandHelpClass: typeof CustomCommandHelp;
|
|
19
|
-
formatCommands(commands: Command.Loadable[]): string;
|
|
20
19
|
}
|
|
21
20
|
export {};
|
package/dist/help.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import { Help as BaseHelp } from '@oclif/core';
|
|
2
2
|
import { CommandHelp as BaseCommandHelp } from '@oclif/core/help';
|
|
3
|
-
/**
|
|
4
|
-
* Extra commands to include in the top-level COMMANDS list.
|
|
5
|
-
* These are nested commands promoted for discoverability.
|
|
6
|
-
*/
|
|
7
|
-
const PROMOTED_COMMANDS = [
|
|
8
|
-
{ description: 'Create a new workspace', label: 'workspace create' },
|
|
9
|
-
{ description: 'List workspaces', label: 'workspace list' },
|
|
10
|
-
{ description: 'Pull a workspace to local files', label: 'workspace pull' },
|
|
11
|
-
{ description: 'Push local documents to a workspace', label: 'workspace push' },
|
|
12
|
-
];
|
|
13
3
|
/**
|
|
14
4
|
* Custom CommandHelp class that extends the default to display environment variables
|
|
15
5
|
* alongside flag descriptions
|
|
@@ -29,36 +19,8 @@ class CustomCommandHelp extends BaseCommandHelp {
|
|
|
29
19
|
}
|
|
30
20
|
}
|
|
31
21
|
/**
|
|
32
|
-
* Custom Help class that
|
|
22
|
+
* Custom Help class that uses CustomCommandHelp
|
|
33
23
|
*/
|
|
34
24
|
export default class Help extends BaseHelp {
|
|
35
25
|
CommandHelpClass = CustomCommandHelp;
|
|
36
|
-
formatCommands(commands) {
|
|
37
|
-
if (commands.length === 0 && PROMOTED_COMMANDS.length === 0)
|
|
38
|
-
return '';
|
|
39
|
-
// Check before IDs are mutated: root help has top-level commands (no colons)
|
|
40
|
-
const isRootHelp = commands.some((c) => !c.id.includes(':'));
|
|
41
|
-
const entries = commands
|
|
42
|
-
.filter((c) => (this.opts.hideAliasesFromRoot ? !c.aliases?.includes(c.id) : true))
|
|
43
|
-
.filter((c) => c.id !== 'plugins')
|
|
44
|
-
.map((c) => {
|
|
45
|
-
if (this.config.topicSeparator !== ':')
|
|
46
|
-
c.id = c.id.replaceAll(':', this.config.topicSeparator);
|
|
47
|
-
const summary = this.summary(c);
|
|
48
|
-
return [c.id, summary ? summary.replace(/\u001B\[\d+m/g, '') : ''];
|
|
49
|
-
});
|
|
50
|
-
// Only add promoted commands at the root level, not within a specific topic
|
|
51
|
-
if (isRootHelp) {
|
|
52
|
-
for (const promoted of PROMOTED_COMMANDS) {
|
|
53
|
-
entries.push([promoted.label, promoted.description]);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
entries.sort((a, b) => a[0].localeCompare(b[0]));
|
|
57
|
-
const body = this.renderList(entries, {
|
|
58
|
-
indentation: 2,
|
|
59
|
-
spacer: '\n',
|
|
60
|
-
stripAnsi: this.opts.stripAnsi,
|
|
61
|
-
});
|
|
62
|
-
return this.section('COMMANDS', body + `\n\n\x1b[2mSee xano <topic> --help for all commands in a topic.\x1b[0m`);
|
|
63
|
-
}
|
|
64
26
|
}
|