@xano/cli 0.0.95-beta.2 → 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 +15 -8
- package/dist/base-command.d.ts +24 -0
- package/dist/base-command.js +37 -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 +2404 -2888
- 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,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxGet extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import BaseCommand from '../../../base-command.js';
|
|
3
|
+
export default class SandboxGet extends BaseCommand {
|
|
4
|
+
static description = 'Get your sandbox environment (creates one if it does not exist)';
|
|
5
|
+
static examples = [
|
|
6
|
+
`$ xano sandbox get
|
|
7
|
+
Sandbox Environment: (tc24-abcd-x1y2)
|
|
8
|
+
State: ok
|
|
9
|
+
License: tier1
|
|
10
|
+
`,
|
|
11
|
+
`$ xano sandbox get -o json`,
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
...BaseCommand.baseFlags,
|
|
15
|
+
output: Flags.string({
|
|
16
|
+
char: 'o',
|
|
17
|
+
default: 'summary',
|
|
18
|
+
description: 'Output format',
|
|
19
|
+
options: ['summary', 'json'],
|
|
20
|
+
required: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags } = await this.parse(SandboxGet);
|
|
25
|
+
const { profile } = this.resolveProfile(flags);
|
|
26
|
+
try {
|
|
27
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
28
|
+
if (flags.output === 'json') {
|
|
29
|
+
this.log(JSON.stringify(tenant, null, 2));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.log(`Sandbox Environment: ${tenant.display || tenant.name} (${tenant.name})`);
|
|
33
|
+
if (tenant.state)
|
|
34
|
+
this.log(` State: ${tenant.state}`);
|
|
35
|
+
if (tenant.xano_domain)
|
|
36
|
+
this.log(` Domain: ${tenant.xano_domain}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error instanceof Error) {
|
|
41
|
+
this.error(`Failed to get sandbox environment: ${error.message}`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.error(`Failed to get sandbox environment: ${String(error)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxLicenseGet extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,28 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import BaseCommand from '../../../../base-command.js';
|
|
5
|
-
export default class
|
|
6
|
-
static
|
|
7
|
-
tenant_name: Args.string({
|
|
8
|
-
description: 'Ephemeral tenant name',
|
|
9
|
-
required: true,
|
|
10
|
-
}),
|
|
11
|
-
};
|
|
12
|
-
static description = 'Get the license for an ephemeral tenant';
|
|
5
|
+
export default class SandboxLicenseGet extends BaseCommand {
|
|
6
|
+
static description = 'Get the license for a sandbox environment';
|
|
13
7
|
static examples = [
|
|
14
|
-
`$ xano
|
|
15
|
-
License saved to
|
|
8
|
+
`$ xano sandbox license get
|
|
9
|
+
License saved to license_<tenant>.yaml
|
|
16
10
|
`,
|
|
17
|
-
`$ xano
|
|
18
|
-
`$ xano
|
|
19
|
-
`$ xano
|
|
11
|
+
`$ xano sandbox license get --file ./my-license.yaml`,
|
|
12
|
+
`$ xano sandbox license get --view`,
|
|
13
|
+
`$ xano sandbox license get -o json`,
|
|
20
14
|
];
|
|
21
15
|
static flags = {
|
|
22
16
|
...BaseCommand.baseFlags,
|
|
23
17
|
file: Flags.string({
|
|
24
18
|
char: 'f',
|
|
25
|
-
description: 'Output file path (default: license_<
|
|
19
|
+
description: 'Output file path (default: license_<sandbox_name>.yaml)',
|
|
26
20
|
required: false,
|
|
27
21
|
}),
|
|
28
22
|
output: Flags.string({
|
|
@@ -39,21 +33,11 @@ License saved to license_my-tenant.yaml
|
|
|
39
33
|
}),
|
|
40
34
|
};
|
|
41
35
|
async run() {
|
|
42
|
-
const {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
const profile = credentials.profiles[profileName];
|
|
49
|
-
if (!profile.instance_origin) {
|
|
50
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
51
|
-
}
|
|
52
|
-
if (!profile.access_token) {
|
|
53
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
54
|
-
}
|
|
55
|
-
const tenantName = args.tenant_name;
|
|
56
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/license`;
|
|
36
|
+
const { flags } = await this.parse(SandboxLicenseGet);
|
|
37
|
+
const { profile } = this.resolveProfile(flags);
|
|
38
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
39
|
+
const tenantName = tenant.name;
|
|
40
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/license`;
|
|
57
41
|
try {
|
|
58
42
|
const response = await this.verboseFetch(apiUrl, {
|
|
59
43
|
headers: {
|
|
@@ -84,10 +68,10 @@ License saved to license_my-tenant.yaml
|
|
|
84
68
|
}
|
|
85
69
|
catch (error) {
|
|
86
70
|
if (error instanceof Error) {
|
|
87
|
-
this.error(`Failed to get
|
|
71
|
+
this.error(`Failed to get sandbox environment license: ${error.message}`);
|
|
88
72
|
}
|
|
89
73
|
else {
|
|
90
|
-
this.error(`Failed to get
|
|
74
|
+
this.error(`Failed to get sandbox environment license: ${String(error)}`);
|
|
91
75
|
}
|
|
92
76
|
}
|
|
93
77
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxLicenseSet extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import BaseCommand from '../../../../base-command.js';
|
|
5
|
-
export default class
|
|
6
|
-
static
|
|
7
|
-
tenant_name: Args.string({
|
|
8
|
-
description: 'Ephemeral tenant name',
|
|
9
|
-
required: true,
|
|
10
|
-
}),
|
|
11
|
-
};
|
|
12
|
-
static description = 'Set/update the license for an ephemeral tenant';
|
|
5
|
+
export default class SandboxLicenseSet extends BaseCommand {
|
|
6
|
+
static description = 'Set/update the license for a sandbox environment';
|
|
13
7
|
static examples = [
|
|
14
|
-
`$ xano
|
|
15
|
-
Reads from
|
|
8
|
+
`$ xano sandbox license set
|
|
9
|
+
Reads from license_<tenant>.yaml
|
|
16
10
|
`,
|
|
17
|
-
`$ xano
|
|
18
|
-
`$ xano
|
|
19
|
-
`$ xano
|
|
11
|
+
`$ xano sandbox license set --file ./license.yaml`,
|
|
12
|
+
`$ xano sandbox license set --value 'key: value'`,
|
|
13
|
+
`$ xano sandbox license set -o json`,
|
|
20
14
|
];
|
|
21
15
|
static flags = {
|
|
22
16
|
...BaseCommand.baseFlags,
|
|
@@ -28,7 +22,7 @@ Reads from license_my-tenant.yaml
|
|
|
28
22
|
}),
|
|
29
23
|
file: Flags.string({
|
|
30
24
|
char: 'f',
|
|
31
|
-
description: 'Path to license file (default: license_<
|
|
25
|
+
description: 'Path to license file (default: license_<sandbox_name>.yaml)',
|
|
32
26
|
exclusive: ['value'],
|
|
33
27
|
required: false,
|
|
34
28
|
}),
|
|
@@ -46,8 +40,10 @@ Reads from license_my-tenant.yaml
|
|
|
46
40
|
}),
|
|
47
41
|
};
|
|
48
42
|
async run() {
|
|
49
|
-
const {
|
|
50
|
-
const
|
|
43
|
+
const { flags } = await this.parse(SandboxLicenseSet);
|
|
44
|
+
const { profile } = this.resolveProfile(flags);
|
|
45
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
46
|
+
const tenantName = tenant.name;
|
|
51
47
|
let licenseValue;
|
|
52
48
|
let sourceFilePath;
|
|
53
49
|
if (flags.value) {
|
|
@@ -60,19 +56,7 @@ Reads from license_my-tenant.yaml
|
|
|
60
56
|
}
|
|
61
57
|
licenseValue = fs.readFileSync(sourceFilePath, 'utf8');
|
|
62
58
|
}
|
|
63
|
-
const
|
|
64
|
-
const credentials = this.loadCredentialsFile();
|
|
65
|
-
if (!credentials || !(profileName in credentials.profiles)) {
|
|
66
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
67
|
-
}
|
|
68
|
-
const profile = credentials.profiles[profileName];
|
|
69
|
-
if (!profile.instance_origin) {
|
|
70
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
71
|
-
}
|
|
72
|
-
if (!profile.access_token) {
|
|
73
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
74
|
-
}
|
|
75
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${tenantName}/license`;
|
|
59
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/license`;
|
|
76
60
|
try {
|
|
77
61
|
const response = await this.verboseFetch(apiUrl, {
|
|
78
62
|
body: JSON.stringify({ value: licenseValue }),
|
|
@@ -92,7 +76,7 @@ Reads from license_my-tenant.yaml
|
|
|
92
76
|
this.log(JSON.stringify(result, null, 2));
|
|
93
77
|
}
|
|
94
78
|
else {
|
|
95
|
-
this.log(`
|
|
79
|
+
this.log(`Sandbox environment license updated successfully for ${tenantName}`);
|
|
96
80
|
}
|
|
97
81
|
if (flags.clean && sourceFilePath && fs.existsSync(sourceFilePath)) {
|
|
98
82
|
fs.unlinkSync(sourceFilePath);
|
|
@@ -101,10 +85,10 @@ Reads from license_my-tenant.yaml
|
|
|
101
85
|
}
|
|
102
86
|
catch (error) {
|
|
103
87
|
if (error instanceof Error) {
|
|
104
|
-
this.error(`Failed to set
|
|
88
|
+
this.error(`Failed to set sandbox environment license: ${error.message}`);
|
|
105
89
|
}
|
|
106
90
|
else {
|
|
107
|
-
this.error(`Failed to set
|
|
91
|
+
this.error(`Failed to set sandbox environment license: ${String(error)}`);
|
|
108
92
|
}
|
|
109
93
|
}
|
|
110
94
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class
|
|
2
|
+
export default class SandboxPull extends BaseCommand {
|
|
3
3
|
static args: {
|
|
4
4
|
directory: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
@@ -9,7 +9,6 @@ export default class EphemeralPull extends BaseCommand {
|
|
|
9
9
|
draft: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
env: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
11
|
records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
12
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
13
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
14
|
};
|
|
@@ -4,19 +4,19 @@ import BaseCommand from '../../../base-command.js';
|
|
|
4
4
|
import { buildApiGroupFolderResolver, parseDocument } from '../../../utils/document-parser.js';
|
|
5
5
|
import * as fs from 'node:fs';
|
|
6
6
|
import * as path from 'node:path';
|
|
7
|
-
export default class
|
|
7
|
+
export default class SandboxPull extends BaseCommand {
|
|
8
8
|
static args = {
|
|
9
9
|
directory: Args.string({
|
|
10
10
|
description: 'Output directory for pulled documents',
|
|
11
11
|
required: true,
|
|
12
12
|
}),
|
|
13
13
|
};
|
|
14
|
-
static description = 'Pull
|
|
14
|
+
static description = 'Pull documents from your sandbox environment and split into individual files';
|
|
15
15
|
static examples = [
|
|
16
|
-
`$ xano
|
|
17
|
-
Pulled 42 documents from
|
|
16
|
+
`$ xano sandbox pull ./my-sandbox
|
|
17
|
+
Pulled 42 documents from sandbox environment tc24-abcd-x1y2 to ./my-sandbox
|
|
18
18
|
`,
|
|
19
|
-
`$ xano
|
|
19
|
+
`$ xano sandbox pull ./backup --env --records`,
|
|
20
20
|
];
|
|
21
21
|
static flags = {
|
|
22
22
|
...BaseCommand.baseFlags,
|
|
@@ -35,33 +35,18 @@ Pulled 42 documents from ephemeral tenant my-tenant to ./my-tenant
|
|
|
35
35
|
description: 'Include records',
|
|
36
36
|
required: false,
|
|
37
37
|
}),
|
|
38
|
-
tenant: Flags.string({
|
|
39
|
-
char: 't',
|
|
40
|
-
description: 'Ephemeral tenant name to pull from',
|
|
41
|
-
required: true,
|
|
42
|
-
}),
|
|
43
38
|
};
|
|
44
39
|
async run() {
|
|
45
|
-
const { args, flags } = await this.parse(
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
50
|
-
}
|
|
51
|
-
const profile = credentials.profiles[profileName];
|
|
52
|
-
if (!profile.instance_origin) {
|
|
53
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
54
|
-
}
|
|
55
|
-
if (!profile.access_token) {
|
|
56
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
57
|
-
}
|
|
58
|
-
const tenantName = flags.tenant;
|
|
40
|
+
const { args, flags } = await this.parse(SandboxPull);
|
|
41
|
+
const { profile } = this.resolveProfile(flags);
|
|
42
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
43
|
+
const tenantName = tenant.name;
|
|
59
44
|
const queryParams = new URLSearchParams({
|
|
60
45
|
env: flags.env.toString(),
|
|
61
46
|
include_draft: flags.draft.toString(),
|
|
62
47
|
records: flags.records.toString(),
|
|
63
48
|
});
|
|
64
|
-
const apiUrl = `${profile.instance_origin}/api:meta/
|
|
49
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/multidoc?${queryParams.toString()}`;
|
|
65
50
|
let responseText;
|
|
66
51
|
try {
|
|
67
52
|
const response = await this.verboseFetch(apiUrl, {
|
|
@@ -189,7 +174,7 @@ Pulled 42 documents from ephemeral tenant my-tenant to ./my-tenant
|
|
|
189
174
|
fs.writeFileSync(filePath, doc.content, 'utf8');
|
|
190
175
|
writtenCount++;
|
|
191
176
|
}
|
|
192
|
-
this.log(`Pulled ${writtenCount} documents from
|
|
177
|
+
this.log(`Pulled ${writtenCount} documents from sandbox environment ${tenantName} to ${args.directory}`);
|
|
193
178
|
}
|
|
194
179
|
sanitizeFilename(name) {
|
|
195
180
|
return snakeCase(name.replaceAll('"', ''));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class
|
|
2
|
+
export default class SandboxPush extends BaseCommand {
|
|
3
3
|
static args: {
|
|
4
4
|
directory: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
@@ -8,7 +8,6 @@ export default class EphemeralPush extends BaseCommand {
|
|
|
8
8
|
static flags: {
|
|
9
9
|
env: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
11
|
transaction: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
12
|
truncate: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
13
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -3,20 +3,20 @@ import BaseCommand from '../../../base-command.js';
|
|
|
3
3
|
import { findFilesWithGuid } from '../../../utils/document-parser.js';
|
|
4
4
|
import * as fs from 'node:fs';
|
|
5
5
|
import * as path from 'node:path';
|
|
6
|
-
export default class
|
|
6
|
+
export default class SandboxPush extends BaseCommand {
|
|
7
7
|
static args = {
|
|
8
8
|
directory: Args.string({
|
|
9
|
-
description: 'Directory containing documents to push (as produced by
|
|
9
|
+
description: 'Directory containing documents to push (as produced by sandbox pull or workspace pull)',
|
|
10
10
|
required: true,
|
|
11
11
|
}),
|
|
12
12
|
};
|
|
13
|
-
static description = 'Push local documents to
|
|
13
|
+
static description = 'Push local documents to your sandbox environment via multidoc import';
|
|
14
14
|
static examples = [
|
|
15
|
-
`$ xano
|
|
16
|
-
Pushed 42 documents to
|
|
15
|
+
`$ xano sandbox push ./my-workspace
|
|
16
|
+
Pushed 42 documents to sandbox environment tc24-abcd-x1y2 from ./my-workspace
|
|
17
17
|
`,
|
|
18
|
-
`$ xano
|
|
19
|
-
`$ xano
|
|
18
|
+
`$ xano sandbox push ./backup --records --env`,
|
|
19
|
+
`$ xano sandbox push ./my-workspace --truncate`,
|
|
20
20
|
];
|
|
21
21
|
static flags = {
|
|
22
22
|
...BaseCommand.baseFlags,
|
|
@@ -30,11 +30,6 @@ Pushed 42 documents to ephemeral tenant my-tenant from ./my-workspace
|
|
|
30
30
|
description: 'Include records in import',
|
|
31
31
|
required: false,
|
|
32
32
|
}),
|
|
33
|
-
tenant: Flags.string({
|
|
34
|
-
char: 't',
|
|
35
|
-
description: 'Ephemeral tenant name to push to',
|
|
36
|
-
required: true,
|
|
37
|
-
}),
|
|
38
33
|
transaction: Flags.boolean({
|
|
39
34
|
allowNo: true,
|
|
40
35
|
default: true,
|
|
@@ -48,20 +43,10 @@ Pushed 42 documents to ephemeral tenant my-tenant from ./my-workspace
|
|
|
48
43
|
}),
|
|
49
44
|
};
|
|
50
45
|
async run() {
|
|
51
|
-
const { args, flags } = await this.parse(
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
this.error(`Profile '${profileName}' not found.\n` + `Create a profile using 'xano profile create'`);
|
|
56
|
-
}
|
|
57
|
-
const profile = credentials.profiles[profileName];
|
|
58
|
-
if (!profile.instance_origin) {
|
|
59
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
60
|
-
}
|
|
61
|
-
if (!profile.access_token) {
|
|
62
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
63
|
-
}
|
|
64
|
-
const tenantName = flags.tenant;
|
|
46
|
+
const { args, flags } = await this.parse(SandboxPush);
|
|
47
|
+
const { profile } = this.resolveProfile(flags);
|
|
48
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
49
|
+
const tenantName = tenant.name;
|
|
65
50
|
const inputDir = path.resolve(args.directory);
|
|
66
51
|
if (!fs.existsSync(inputDir)) {
|
|
67
52
|
this.error(`Directory not found: ${inputDir}`);
|
|
@@ -90,7 +75,7 @@ Pushed 42 documents to ephemeral tenant my-tenant from ./my-workspace
|
|
|
90
75
|
transaction: flags.transaction.toString(),
|
|
91
76
|
truncate: flags.truncate.toString(),
|
|
92
77
|
});
|
|
93
|
-
const apiUrl = `${profile.instance_origin}/api:meta/
|
|
78
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${tenantName}/multidoc?${queryParams.toString()}`;
|
|
94
79
|
const startTime = Date.now();
|
|
95
80
|
try {
|
|
96
81
|
const response = await this.verboseFetch(apiUrl, {
|
|
@@ -139,7 +124,7 @@ Pushed 42 documents to ephemeral tenant my-tenant from ./my-workspace
|
|
|
139
124
|
}
|
|
140
125
|
}
|
|
141
126
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
142
|
-
this.log(`Pushed ${documentEntries.length} documents to
|
|
127
|
+
this.log(`Pushed ${documentEntries.length} documents to sandbox environment ${tenantName} from ${args.directory} in ${elapsed}s`);
|
|
143
128
|
}
|
|
144
129
|
collectFiles(dir) {
|
|
145
130
|
const files = [];
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxReset extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
9
6
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
7
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
8
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
9
|
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import BaseCommand from '../../../base-command.js';
|
|
3
|
+
export default class SandboxReset extends BaseCommand {
|
|
4
|
+
static description = 'Reset your sandbox environment (clears all workspace data and drafts)';
|
|
5
|
+
static examples = [
|
|
6
|
+
`$ xano sandbox reset
|
|
7
|
+
Are you sure you want to reset your sandbox environment? All workspace data and drafts will be cleared. (y/N) y
|
|
8
|
+
Reset sandbox environment tc24-abcd-x1y2
|
|
9
|
+
`,
|
|
10
|
+
`$ xano sandbox reset --force`,
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
...BaseCommand.baseFlags,
|
|
14
|
+
force: Flags.boolean({
|
|
15
|
+
char: 'f',
|
|
16
|
+
default: false,
|
|
17
|
+
description: 'Skip confirmation prompt',
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async run() {
|
|
22
|
+
const { flags } = await this.parse(SandboxReset);
|
|
23
|
+
const { profile } = this.resolveProfile(flags);
|
|
24
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
25
|
+
const tenantName = tenant.name;
|
|
26
|
+
if (!flags.force) {
|
|
27
|
+
const confirmed = await this.confirm(`Are you sure you want to reset your sandbox environment? All workspace data and drafts will be cleared.`);
|
|
28
|
+
if (!confirmed) {
|
|
29
|
+
this.log('Reset cancelled.');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${encodeURIComponent(tenantName)}/reset`;
|
|
34
|
+
try {
|
|
35
|
+
const response = await this.verboseFetch(apiUrl, {
|
|
36
|
+
headers: {
|
|
37
|
+
accept: 'application/json',
|
|
38
|
+
Authorization: `Bearer ${profile.access_token}`,
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
method: 'POST',
|
|
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
|
+
this.log('Sandbox environment has been reset.');
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error instanceof Error) {
|
|
51
|
+
this.error(`Failed to reset sandbox environment: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.error(`Failed to reset sandbox environment: ${String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async confirm(message) {
|
|
59
|
+
const readline = await import('node:readline');
|
|
60
|
+
const rl = readline.createInterface({
|
|
61
|
+
input: process.stdin,
|
|
62
|
+
output: process.stdout,
|
|
63
|
+
});
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
rl.question(`${message} (y/N) `, (answer) => {
|
|
66
|
+
rl.close();
|
|
67
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class
|
|
3
|
-
static args: {
|
|
4
|
-
tenant_name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
2
|
+
export default class SandboxReview extends BaseCommand {
|
|
6
3
|
static description: string;
|
|
7
4
|
static examples: string[];
|
|
8
5
|
static flags: {
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import open from 'open';
|
|
3
3
|
import BaseCommand from '../../../base-command.js';
|
|
4
|
-
export default class
|
|
5
|
-
static
|
|
6
|
-
tenant_name: Args.string({
|
|
7
|
-
description: 'Ephemeral tenant name to impersonate',
|
|
8
|
-
required: true,
|
|
9
|
-
}),
|
|
10
|
-
};
|
|
11
|
-
static description = 'Impersonate an ephemeral tenant and open it in the browser';
|
|
4
|
+
export default class SandboxReview extends BaseCommand {
|
|
5
|
+
static description = 'Open your sandbox environment in the browser to review and promote changes';
|
|
12
6
|
static examples = [
|
|
13
|
-
`$ xano
|
|
7
|
+
`$ xano sandbox review
|
|
14
8
|
Opening browser...
|
|
15
|
-
|
|
9
|
+
Review session started!
|
|
16
10
|
`,
|
|
17
|
-
`$ xano
|
|
18
|
-
`$ xano
|
|
11
|
+
`$ xano sandbox review -u`,
|
|
12
|
+
`$ xano sandbox review -o json`,
|
|
19
13
|
];
|
|
20
14
|
static flags = {
|
|
21
15
|
...BaseCommand.baseFlags,
|
|
@@ -34,21 +28,11 @@ Impersonation successful!
|
|
|
34
28
|
}),
|
|
35
29
|
};
|
|
36
30
|
async run() {
|
|
37
|
-
const {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
const profile = credentials.profiles[profileName];
|
|
44
|
-
if (!profile.instance_origin) {
|
|
45
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
46
|
-
}
|
|
47
|
-
if (!profile.access_token) {
|
|
48
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
49
|
-
}
|
|
50
|
-
const tenantName = args.tenant_name;
|
|
51
|
-
const apiUrl = `${profile.instance_origin}/api:meta/ephemeral/tenant/${encodeURIComponent(tenantName)}/impersonate`;
|
|
31
|
+
const { flags } = await this.parse(SandboxReview);
|
|
32
|
+
const { profile } = this.resolveProfile(flags);
|
|
33
|
+
const tenant = await this.getOrCreateSandbox(profile, flags.verbose);
|
|
34
|
+
const tenantName = tenant.name;
|
|
35
|
+
const apiUrl = `${profile.instance_origin}/api:meta/sandbox/tenant/${encodeURIComponent(tenantName)}/impersonate`;
|
|
52
36
|
try {
|
|
53
37
|
const response = await this.verboseFetch(apiUrl, {
|
|
54
38
|
headers: {
|
|
@@ -80,17 +64,17 @@ Impersonation successful!
|
|
|
80
64
|
else {
|
|
81
65
|
this.log('Opening browser...');
|
|
82
66
|
await open(impersonateUrl);
|
|
83
|
-
this.log('
|
|
67
|
+
this.log('Review session started!');
|
|
84
68
|
}
|
|
85
69
|
}
|
|
86
70
|
process.exit(0);
|
|
87
71
|
}
|
|
88
72
|
catch (error) {
|
|
89
73
|
if (error instanceof Error) {
|
|
90
|
-
this.error(`Failed to
|
|
74
|
+
this.error(`Failed to open sandbox review: ${error.message}`);
|
|
91
75
|
}
|
|
92
76
|
else {
|
|
93
|
-
this.error(`Failed to
|
|
77
|
+
this.error(`Failed to open sandbox review: ${String(error)}`);
|
|
94
78
|
}
|
|
95
79
|
}
|
|
96
80
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import BaseCommand from '../../../../base-command.js';
|
|
2
|
-
export default class
|
|
2
|
+
export default class SandboxUnitTestList 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
|
'obj-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
9
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
10
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
11
|
};
|