@xano/cli 0.0.24 → 0.0.26
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/dist/base-command.d.ts +1 -3
- package/dist/base-command.js +5 -12
- package/dist/commands/function/create/index.d.ts +6 -7
- package/dist/commands/function/create/index.js +55 -55
- package/dist/commands/function/edit/index.d.ts +10 -11
- package/dist/commands/function/edit/index.js +162 -155
- package/dist/commands/function/get/index.d.ts +5 -6
- package/dist/commands/function/get/index.js +60 -55
- package/dist/commands/function/list/index.d.ts +5 -6
- package/dist/commands/function/list/index.js +52 -52
- package/dist/commands/profile/create/index.d.ts +6 -6
- package/dist/commands/profile/create/index.js +37 -37
- package/dist/commands/profile/delete/index.d.ts +2 -2
- package/dist/commands/profile/delete/index.js +9 -9
- package/dist/commands/profile/edit/index.d.ts +7 -8
- package/dist/commands/profile/edit/index.js +48 -48
- package/dist/commands/profile/get-default/index.js +1 -1
- package/dist/commands/profile/list/index.d.ts +2 -2
- package/dist/commands/profile/list/index.js +9 -9
- package/dist/commands/profile/me/index.d.ts +3 -4
- package/dist/commands/profile/me/index.js +21 -21
- package/dist/commands/profile/project/index.js +1 -1
- package/dist/commands/profile/set-default/index.js +1 -1
- package/dist/commands/profile/token/index.js +1 -1
- package/dist/commands/profile/wizard/index.d.ts +4 -5
- package/dist/commands/profile/wizard/index.js +108 -142
- package/dist/commands/run/env/delete/index.d.ts +2 -3
- package/dist/commands/run/env/delete/index.js +10 -10
- package/dist/commands/run/env/get/index.d.ts +2 -3
- package/dist/commands/run/env/get/index.js +11 -11
- package/dist/commands/run/env/list/index.d.ts +2 -3
- package/dist/commands/run/env/list/index.js +19 -17
- package/dist/commands/run/env/set/index.d.ts +2 -3
- package/dist/commands/run/env/set/index.js +5 -5
- package/dist/commands/run/exec/index.d.ts +8 -19
- package/dist/commands/run/exec/index.js +108 -186
- package/dist/commands/run/info/index.d.ts +4 -5
- package/dist/commands/run/info/index.js +27 -27
- package/dist/commands/run/projects/create/index.d.ts +3 -4
- package/dist/commands/run/projects/create/index.js +23 -23
- package/dist/commands/run/projects/delete/index.d.ts +2 -3
- package/dist/commands/run/projects/delete/index.js +10 -10
- package/dist/commands/run/projects/list/index.d.ts +2 -3
- package/dist/commands/run/projects/list/index.js +12 -12
- package/dist/commands/run/projects/update/index.d.ts +3 -4
- package/dist/commands/run/projects/update/index.js +21 -21
- package/dist/commands/run/secrets/delete/index.d.ts +2 -3
- package/dist/commands/run/secrets/delete/index.js +10 -10
- package/dist/commands/run/secrets/get/index.d.ts +2 -3
- package/dist/commands/run/secrets/get/index.js +11 -11
- package/dist/commands/run/secrets/list/index.d.ts +2 -3
- package/dist/commands/run/secrets/list/index.js +24 -22
- package/dist/commands/run/secrets/set/index.d.ts +3 -4
- package/dist/commands/run/secrets/set/index.js +16 -16
- package/dist/commands/run/sessions/delete/index.d.ts +2 -3
- package/dist/commands/run/sessions/delete/index.js +10 -10
- package/dist/commands/run/sessions/get/index.d.ts +2 -3
- package/dist/commands/run/sessions/get/index.js +11 -11
- package/dist/commands/run/sessions/list/index.d.ts +2 -3
- package/dist/commands/run/sessions/list/index.js +11 -11
- package/dist/commands/run/sessions/start/index.d.ts +2 -3
- package/dist/commands/run/sessions/start/index.js +11 -11
- package/dist/commands/run/sessions/stop/index.d.ts +2 -3
- package/dist/commands/run/sessions/stop/index.js +11 -11
- package/dist/commands/run/sink/get/index.d.ts +2 -3
- package/dist/commands/run/sink/get/index.js +11 -11
- package/dist/commands/static_host/build/create/index.d.ts +4 -5
- package/dist/commands/static_host/build/create/index.js +33 -33
- package/dist/commands/static_host/build/get/index.d.ts +4 -5
- package/dist/commands/static_host/build/get/index.js +20 -20
- package/dist/commands/static_host/build/list/index.d.ts +3 -4
- package/dist/commands/static_host/build/list/index.js +31 -31
- package/dist/commands/static_host/list/index.d.ts +3 -4
- package/dist/commands/static_host/list/index.js +31 -31
- package/dist/commands/workspace/list/index.d.ts +2 -3
- package/dist/commands/workspace/list/index.js +15 -15
- package/dist/commands/workspace/pull/index.d.ts +4 -5
- package/dist/commands/workspace/pull/index.js +52 -47
- package/dist/commands/workspace/push/index.d.ts +0 -1
- package/dist/commands/workspace/push/index.js +4 -4
- package/dist/help.d.ts +1 -1
- package/dist/lib/base-run-command.d.ts +6 -6
- package/dist/lib/base-run-command.js +6 -8
- package/dist/lib/run-http-client.d.ts +18 -24
- package/dist/lib/run-http-client.js +61 -96
- package/dist/lib/run-types.d.ts +80 -80
- package/oclif.manifest.json +888 -2031
- package/package.json +5 -2
- package/dist/commands/branch/create/index.d.ts +0 -17
- package/dist/commands/branch/create/index.js +0 -164
- package/dist/commands/branch/delete/index.d.ts +0 -18
- package/dist/commands/branch/delete/index.js +0 -156
- package/dist/commands/branch/edit/index.d.ts +0 -19
- package/dist/commands/branch/edit/index.js +0 -166
- package/dist/commands/branch/get/index.d.ts +0 -16
- package/dist/commands/branch/get/index.js +0 -135
- package/dist/commands/branch/list/index.d.ts +0 -18
- package/dist/commands/branch/list/index.js +0 -138
- package/dist/commands/branch/set-live/index.d.ts +0 -18
- package/dist/commands/branch/set-live/index.js +0 -155
- package/dist/commands/workspace/create/index.d.ts +0 -14
- package/dist/commands/workspace/create/index.js +0 -131
- package/dist/commands/workspace/delete/index.d.ts +0 -20
- package/dist/commands/workspace/delete/index.js +0 -141
- package/dist/commands/workspace/edit/index.d.ts +0 -22
- package/dist/commands/workspace/edit/index.js +0 -176
- package/dist/commands/workspace/get/index.d.ts +0 -18
- package/dist/commands/workspace/get/index.js +0 -136
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import BaseCommand from '../../../base-command.js';
|
|
7
|
-
export default class BranchGet extends BaseCommand {
|
|
8
|
-
static args = {
|
|
9
|
-
branch_label: Args.string({
|
|
10
|
-
description: 'Branch label (e.g., "v1", "dev")',
|
|
11
|
-
required: true,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
static description = 'Get details for a specific branch';
|
|
15
|
-
static examples = [
|
|
16
|
-
`$ xano branch get v1
|
|
17
|
-
Branch: v1 (live)
|
|
18
|
-
Created: 2024-01-15
|
|
19
|
-
`,
|
|
20
|
-
`$ xano branch get dev -w 123
|
|
21
|
-
Branch: dev
|
|
22
|
-
Created: 2024-02-01
|
|
23
|
-
`,
|
|
24
|
-
`$ xano branch get staging --output json
|
|
25
|
-
{
|
|
26
|
-
"created_at": "2024-02-10T09:15:00Z",
|
|
27
|
-
"label": "staging",
|
|
28
|
-
"backup": false,
|
|
29
|
-
"live": false
|
|
30
|
-
}
|
|
31
|
-
`,
|
|
32
|
-
];
|
|
33
|
-
static flags = {
|
|
34
|
-
...BaseCommand.baseFlags,
|
|
35
|
-
output: Flags.string({
|
|
36
|
-
char: 'o',
|
|
37
|
-
default: 'summary',
|
|
38
|
-
description: 'Output format',
|
|
39
|
-
options: ['summary', 'json'],
|
|
40
|
-
required: false,
|
|
41
|
-
}),
|
|
42
|
-
workspace: Flags.integer({
|
|
43
|
-
char: 'w',
|
|
44
|
-
description: 'Workspace ID (uses profile workspace if not provided)',
|
|
45
|
-
required: false,
|
|
46
|
-
}),
|
|
47
|
-
};
|
|
48
|
-
async run() {
|
|
49
|
-
const { args, flags } = await this.parse(BranchGet);
|
|
50
|
-
// Get profile name (default or from flag/env)
|
|
51
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
52
|
-
// Load credentials
|
|
53
|
-
const credentials = this.loadCredentials();
|
|
54
|
-
// Get the profile configuration
|
|
55
|
-
if (!(profileName in credentials.profiles)) {
|
|
56
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
57
|
-
`Create a profile using 'xano profile create'`);
|
|
58
|
-
}
|
|
59
|
-
const profile = credentials.profiles[profileName];
|
|
60
|
-
// Validate required fields
|
|
61
|
-
if (!profile.instance_origin) {
|
|
62
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
63
|
-
}
|
|
64
|
-
if (!profile.access_token) {
|
|
65
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
66
|
-
}
|
|
67
|
-
// Get workspace ID from flag or profile
|
|
68
|
-
const workspaceId = flags.workspace || profile.workspace;
|
|
69
|
-
if (!workspaceId) {
|
|
70
|
-
this.error('No workspace ID provided. Either use --workspace flag or set one in your profile.\n' +
|
|
71
|
-
'Usage: xano branch get <branch_label> --workspace <workspace_id>');
|
|
72
|
-
}
|
|
73
|
-
const branchLabel = args.branch_label;
|
|
74
|
-
// Construct the API URL
|
|
75
|
-
const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/branch/${encodeURIComponent(branchLabel)}`;
|
|
76
|
-
// Fetch branch from the API
|
|
77
|
-
try {
|
|
78
|
-
const response = await fetch(apiUrl, {
|
|
79
|
-
headers: {
|
|
80
|
-
'accept': 'application/json',
|
|
81
|
-
'Authorization': `Bearer ${profile.access_token}`,
|
|
82
|
-
},
|
|
83
|
-
method: 'GET',
|
|
84
|
-
});
|
|
85
|
-
if (!response.ok) {
|
|
86
|
-
const errorText = await response.text();
|
|
87
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
88
|
-
}
|
|
89
|
-
const branch = await response.json();
|
|
90
|
-
// Output results
|
|
91
|
-
if (flags.output === 'json') {
|
|
92
|
-
this.log(JSON.stringify(branch, null, 2));
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// summary format
|
|
96
|
-
const liveIndicator = branch.live ? ' (live)' : '';
|
|
97
|
-
const backupIndicator = branch.backup ? ' (backup)' : '';
|
|
98
|
-
this.log(`Branch: ${branch.label}${liveIndicator}${backupIndicator}`);
|
|
99
|
-
if (branch.created_at) {
|
|
100
|
-
const createdDate = branch.created_at.split('T')[0];
|
|
101
|
-
this.log(` Created: ${createdDate}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
if (error instanceof Error) {
|
|
107
|
-
this.error(`Failed to fetch branch: ${error.message}`);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
this.error(`Failed to fetch branch: ${String(error)}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
loadCredentials() {
|
|
115
|
-
const configDir = path.join(os.homedir(), '.xano');
|
|
116
|
-
const credentialsPath = path.join(configDir, 'credentials.yaml');
|
|
117
|
-
// Check if credentials file exists
|
|
118
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
119
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
120
|
-
`Create a profile using 'xano profile create'`);
|
|
121
|
-
}
|
|
122
|
-
// Read credentials file
|
|
123
|
-
try {
|
|
124
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
125
|
-
const parsed = yaml.load(fileContent);
|
|
126
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
127
|
-
this.error('Credentials file has invalid format.');
|
|
128
|
-
}
|
|
129
|
-
return parsed;
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class BranchList extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
workspace_id: import("@oclif/core/interfaces").Arg<number | undefined, {
|
|
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
|
-
private loadCredentials;
|
|
18
|
-
}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import BaseCommand from '../../../base-command.js';
|
|
7
|
-
export default class BranchList extends BaseCommand {
|
|
8
|
-
static args = {
|
|
9
|
-
workspace_id: Args.integer({
|
|
10
|
-
description: 'Workspace ID (uses profile workspace if not provided)',
|
|
11
|
-
required: false,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
static description = 'List all branches in a workspace';
|
|
15
|
-
static examples = [
|
|
16
|
-
`$ xano branch list
|
|
17
|
-
Available branches:
|
|
18
|
-
- v1 (live)
|
|
19
|
-
- dev
|
|
20
|
-
- staging
|
|
21
|
-
`,
|
|
22
|
-
`$ xano branch list 123
|
|
23
|
-
Available branches:
|
|
24
|
-
- v1 (live)
|
|
25
|
-
- feature-auth
|
|
26
|
-
`,
|
|
27
|
-
`$ xano branch list --output json
|
|
28
|
-
[
|
|
29
|
-
{
|
|
30
|
-
"created_at": "2024-01-15T10:30:00Z",
|
|
31
|
-
"label": "v1",
|
|
32
|
-
"backup": false,
|
|
33
|
-
"live": true
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
`,
|
|
37
|
-
];
|
|
38
|
-
static flags = {
|
|
39
|
-
...BaseCommand.baseFlags,
|
|
40
|
-
output: Flags.string({
|
|
41
|
-
char: 'o',
|
|
42
|
-
default: 'summary',
|
|
43
|
-
description: 'Output format',
|
|
44
|
-
options: ['summary', 'json'],
|
|
45
|
-
required: false,
|
|
46
|
-
}),
|
|
47
|
-
};
|
|
48
|
-
async run() {
|
|
49
|
-
const { args, flags } = await this.parse(BranchList);
|
|
50
|
-
// Get profile name (default or from flag/env)
|
|
51
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
52
|
-
// Load credentials
|
|
53
|
-
const credentials = this.loadCredentials();
|
|
54
|
-
// Get the profile configuration
|
|
55
|
-
if (!(profileName in credentials.profiles)) {
|
|
56
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
57
|
-
`Create a profile using 'xano profile create'`);
|
|
58
|
-
}
|
|
59
|
-
const profile = credentials.profiles[profileName];
|
|
60
|
-
// Validate required fields
|
|
61
|
-
if (!profile.instance_origin) {
|
|
62
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
63
|
-
}
|
|
64
|
-
if (!profile.access_token) {
|
|
65
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
66
|
-
}
|
|
67
|
-
// Get workspace ID from args or profile
|
|
68
|
-
const workspaceId = args.workspace_id || profile.workspace;
|
|
69
|
-
if (!workspaceId) {
|
|
70
|
-
this.error('No workspace ID provided. Either pass a workspace ID as an argument or set one in your profile.\n' +
|
|
71
|
-
'Usage: xano branch list [workspace_id]');
|
|
72
|
-
}
|
|
73
|
-
// Construct the API URL
|
|
74
|
-
const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/branch`;
|
|
75
|
-
// Fetch branches from the API
|
|
76
|
-
try {
|
|
77
|
-
const response = await fetch(apiUrl, {
|
|
78
|
-
headers: {
|
|
79
|
-
'accept': 'application/json',
|
|
80
|
-
'Authorization': `Bearer ${profile.access_token}`,
|
|
81
|
-
},
|
|
82
|
-
method: 'GET',
|
|
83
|
-
});
|
|
84
|
-
if (!response.ok) {
|
|
85
|
-
const errorText = await response.text();
|
|
86
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
87
|
-
}
|
|
88
|
-
const branches = await response.json();
|
|
89
|
-
// Output results
|
|
90
|
-
if (flags.output === 'json') {
|
|
91
|
-
this.log(JSON.stringify(branches, null, 2));
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// summary format
|
|
95
|
-
if (branches.length === 0) {
|
|
96
|
-
this.log('No branches found');
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
this.log('Available branches:');
|
|
100
|
-
for (const branch of branches) {
|
|
101
|
-
const liveIndicator = branch.live ? ' (live)' : '';
|
|
102
|
-
const backupIndicator = branch.backup ? ' (backup)' : '';
|
|
103
|
-
this.log(` - ${branch.label}${liveIndicator}${backupIndicator}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
if (error instanceof Error) {
|
|
110
|
-
this.error(`Failed to fetch branches: ${error.message}`);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
this.error(`Failed to fetch branches: ${String(error)}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
loadCredentials() {
|
|
118
|
-
const configDir = path.join(os.homedir(), '.xano');
|
|
119
|
-
const credentialsPath = path.join(configDir, 'credentials.yaml');
|
|
120
|
-
// Check if credentials file exists
|
|
121
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
122
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
123
|
-
`Create a profile using 'xano profile create'`);
|
|
124
|
-
}
|
|
125
|
-
// Read credentials file
|
|
126
|
-
try {
|
|
127
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
128
|
-
const parsed = yaml.load(fileContent);
|
|
129
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
130
|
-
this.error('Credentials file has invalid format.');
|
|
131
|
-
}
|
|
132
|
-
return parsed;
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class BranchSetLive extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
branch_label: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
-
};
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
workspace: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
};
|
|
15
|
-
run(): Promise<void>;
|
|
16
|
-
private confirm;
|
|
17
|
-
private loadCredentials;
|
|
18
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import BaseCommand from '../../../base-command.js';
|
|
7
|
-
export default class BranchSetLive extends BaseCommand {
|
|
8
|
-
static args = {
|
|
9
|
-
branch_label: Args.string({
|
|
10
|
-
description: 'Branch label to set as live (use "v1" for default branch)',
|
|
11
|
-
required: true,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
static description = 'Set a branch as the live (active) branch for API requests';
|
|
15
|
-
static examples = [
|
|
16
|
-
`$ xano branch set-live staging
|
|
17
|
-
Are you sure you want to set 'staging' as the live branch? (y/N) y
|
|
18
|
-
Branch 'staging' is now live
|
|
19
|
-
`,
|
|
20
|
-
`$ xano branch set-live v1 --force
|
|
21
|
-
Branch 'v1' is now live
|
|
22
|
-
`,
|
|
23
|
-
`$ xano branch set-live production -f -o json
|
|
24
|
-
{
|
|
25
|
-
"created_at": "2024-02-10T09:15:00Z",
|
|
26
|
-
"label": "production",
|
|
27
|
-
"backup": false,
|
|
28
|
-
"live": true
|
|
29
|
-
}
|
|
30
|
-
`,
|
|
31
|
-
];
|
|
32
|
-
static flags = {
|
|
33
|
-
...BaseCommand.baseFlags,
|
|
34
|
-
force: Flags.boolean({
|
|
35
|
-
char: 'f',
|
|
36
|
-
default: false,
|
|
37
|
-
description: 'Skip confirmation prompt',
|
|
38
|
-
required: false,
|
|
39
|
-
}),
|
|
40
|
-
output: Flags.string({
|
|
41
|
-
char: 'o',
|
|
42
|
-
default: 'summary',
|
|
43
|
-
description: 'Output format',
|
|
44
|
-
options: ['summary', 'json'],
|
|
45
|
-
required: false,
|
|
46
|
-
}),
|
|
47
|
-
workspace: Flags.integer({
|
|
48
|
-
char: 'w',
|
|
49
|
-
description: 'Workspace ID (uses profile workspace if not provided)',
|
|
50
|
-
required: false,
|
|
51
|
-
}),
|
|
52
|
-
};
|
|
53
|
-
async run() {
|
|
54
|
-
const { args, flags } = await this.parse(BranchSetLive);
|
|
55
|
-
// Get profile name (default or from flag/env)
|
|
56
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
57
|
-
// Load credentials
|
|
58
|
-
const credentials = this.loadCredentials();
|
|
59
|
-
// Get the profile configuration
|
|
60
|
-
if (!(profileName in credentials.profiles)) {
|
|
61
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
62
|
-
`Create a profile using 'xano profile create'`);
|
|
63
|
-
}
|
|
64
|
-
const profile = credentials.profiles[profileName];
|
|
65
|
-
// Validate required fields
|
|
66
|
-
if (!profile.instance_origin) {
|
|
67
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
68
|
-
}
|
|
69
|
-
if (!profile.access_token) {
|
|
70
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
71
|
-
}
|
|
72
|
-
// Get workspace ID from flag or profile
|
|
73
|
-
const workspaceId = flags.workspace || profile.workspace;
|
|
74
|
-
if (!workspaceId) {
|
|
75
|
-
this.error('No workspace ID provided. Either use --workspace flag or set one in your profile.\n' +
|
|
76
|
-
'Usage: xano branch set-live <branch_label> [--workspace <workspace_id>]');
|
|
77
|
-
}
|
|
78
|
-
const branchLabel = args.branch_label;
|
|
79
|
-
// Confirmation prompt unless --force is used
|
|
80
|
-
if (!flags.force) {
|
|
81
|
-
const confirmed = await this.confirm(`Are you sure you want to set '${branchLabel}' as the live branch?`);
|
|
82
|
-
if (!confirmed) {
|
|
83
|
-
this.log('Operation cancelled.');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Construct the API URL
|
|
88
|
-
const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/branch/${encodeURIComponent(branchLabel)}/live`;
|
|
89
|
-
// Set branch as live via the API
|
|
90
|
-
try {
|
|
91
|
-
const response = await fetch(apiUrl, {
|
|
92
|
-
headers: {
|
|
93
|
-
'accept': 'application/json',
|
|
94
|
-
'Authorization': `Bearer ${profile.access_token}`,
|
|
95
|
-
},
|
|
96
|
-
method: 'POST',
|
|
97
|
-
});
|
|
98
|
-
if (!response.ok) {
|
|
99
|
-
const errorText = await response.text();
|
|
100
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
101
|
-
}
|
|
102
|
-
const branch = await response.json();
|
|
103
|
-
// Output results
|
|
104
|
-
if (flags.output === 'json') {
|
|
105
|
-
this.log(JSON.stringify(branch, null, 2));
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
this.log(`Branch '${branch.label}' is now live`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
if (error instanceof Error) {
|
|
113
|
-
this.error(`Failed to set branch as live: ${error.message}`);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
this.error(`Failed to set branch as live: ${String(error)}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
async confirm(message) {
|
|
121
|
-
// Use readline for simple yes/no confirmation
|
|
122
|
-
const readline = await import('node:readline');
|
|
123
|
-
const rl = readline.createInterface({
|
|
124
|
-
input: process.stdin,
|
|
125
|
-
output: process.stdout,
|
|
126
|
-
});
|
|
127
|
-
return new Promise((resolve) => {
|
|
128
|
-
rl.question(`${message} (y/N) `, (answer) => {
|
|
129
|
-
rl.close();
|
|
130
|
-
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
loadCredentials() {
|
|
135
|
-
const configDir = path.join(os.homedir(), '.xano');
|
|
136
|
-
const credentialsPath = path.join(configDir, 'credentials.yaml');
|
|
137
|
-
// Check if credentials file exists
|
|
138
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
139
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
140
|
-
`Create a profile using 'xano profile create'`);
|
|
141
|
-
}
|
|
142
|
-
// Read credentials file
|
|
143
|
-
try {
|
|
144
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
145
|
-
const parsed = yaml.load(fileContent);
|
|
146
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
147
|
-
this.error('Credentials file has invalid format.');
|
|
148
|
-
}
|
|
149
|
-
return parsed;
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class WorkspaceCreate extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
name: import("@oclif/core/interfaces").OptionFlag<string, 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
|
-
private loadCredentials;
|
|
14
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import BaseCommand from '../../../base-command.js';
|
|
7
|
-
export default class WorkspaceCreate extends BaseCommand {
|
|
8
|
-
static description = 'Create a new workspace via the Xano Metadata API';
|
|
9
|
-
static examples = [
|
|
10
|
-
`$ xano workspace create --name "my-workspace"
|
|
11
|
-
Created workspace: my-workspace (ID: 123)
|
|
12
|
-
`,
|
|
13
|
-
`$ xano workspace create --name "my-app" --description "My application workspace"
|
|
14
|
-
Created workspace: my-app (ID: 456)
|
|
15
|
-
Description: My application workspace
|
|
16
|
-
`,
|
|
17
|
-
`$ xano workspace create -n "new-project" -d "New project workspace" -o json
|
|
18
|
-
{
|
|
19
|
-
"id": 789,
|
|
20
|
-
"name": "new-project",
|
|
21
|
-
"description": "New project workspace"
|
|
22
|
-
}
|
|
23
|
-
`,
|
|
24
|
-
];
|
|
25
|
-
static flags = {
|
|
26
|
-
...BaseCommand.baseFlags,
|
|
27
|
-
description: Flags.string({
|
|
28
|
-
char: 'd',
|
|
29
|
-
description: 'Description for the workspace',
|
|
30
|
-
required: false,
|
|
31
|
-
}),
|
|
32
|
-
name: Flags.string({
|
|
33
|
-
char: 'n',
|
|
34
|
-
description: 'Name of the workspace',
|
|
35
|
-
required: true,
|
|
36
|
-
}),
|
|
37
|
-
output: Flags.string({
|
|
38
|
-
char: 'o',
|
|
39
|
-
default: 'summary',
|
|
40
|
-
description: 'Output format',
|
|
41
|
-
options: ['summary', 'json'],
|
|
42
|
-
required: false,
|
|
43
|
-
}),
|
|
44
|
-
};
|
|
45
|
-
async run() {
|
|
46
|
-
const { flags } = await this.parse(WorkspaceCreate);
|
|
47
|
-
// Get profile name (default or from flag/env)
|
|
48
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
49
|
-
// Load credentials
|
|
50
|
-
const credentials = this.loadCredentials();
|
|
51
|
-
// Get the profile configuration
|
|
52
|
-
if (!(profileName in credentials.profiles)) {
|
|
53
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
54
|
-
`Create a profile using 'xano profile create'`);
|
|
55
|
-
}
|
|
56
|
-
const profile = credentials.profiles[profileName];
|
|
57
|
-
// Validate required fields
|
|
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
|
-
// Construct the API URL
|
|
65
|
-
const apiUrl = `${profile.instance_origin}/api:meta/workspace`;
|
|
66
|
-
// Build request body
|
|
67
|
-
const body = {
|
|
68
|
-
name: flags.name,
|
|
69
|
-
};
|
|
70
|
-
if (flags.description) {
|
|
71
|
-
body.description = flags.description;
|
|
72
|
-
}
|
|
73
|
-
// Create workspace via the API
|
|
74
|
-
try {
|
|
75
|
-
const response = await fetch(apiUrl, {
|
|
76
|
-
body: JSON.stringify(body),
|
|
77
|
-
headers: {
|
|
78
|
-
'accept': 'application/json',
|
|
79
|
-
'Authorization': `Bearer ${profile.access_token}`,
|
|
80
|
-
'content-type': 'application/json',
|
|
81
|
-
},
|
|
82
|
-
method: 'POST',
|
|
83
|
-
});
|
|
84
|
-
if (!response.ok) {
|
|
85
|
-
const errorText = await response.text();
|
|
86
|
-
this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
|
|
87
|
-
}
|
|
88
|
-
const workspace = await response.json();
|
|
89
|
-
// Output results
|
|
90
|
-
if (flags.output === 'json') {
|
|
91
|
-
this.log(JSON.stringify(workspace, null, 2));
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// summary format
|
|
95
|
-
this.log(`Created workspace: ${workspace.name} (ID: ${workspace.id})`);
|
|
96
|
-
if (workspace.description) {
|
|
97
|
-
this.log(` Description: ${workspace.description}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
if (error instanceof Error) {
|
|
103
|
-
this.error(`Failed to create workspace: ${error.message}`);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
this.error(`Failed to create workspace: ${String(error)}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
loadCredentials() {
|
|
111
|
-
const configDir = path.join(os.homedir(), '.xano');
|
|
112
|
-
const credentialsPath = path.join(configDir, 'credentials.yaml');
|
|
113
|
-
// Check if credentials file exists
|
|
114
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
115
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
116
|
-
`Create a profile using 'xano profile create'`);
|
|
117
|
-
}
|
|
118
|
-
// Read credentials file
|
|
119
|
-
try {
|
|
120
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
121
|
-
const parsed = yaml.load(fileContent);
|
|
122
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
123
|
-
this.error('Credentials file has invalid format.');
|
|
124
|
-
}
|
|
125
|
-
return parsed;
|
|
126
|
-
}
|
|
127
|
-
catch (error) {
|
|
128
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import BaseCommand from '../../../base-command.js';
|
|
2
|
-
export default class WorkspaceDelete extends BaseCommand {
|
|
3
|
-
static args: {
|
|
4
|
-
workspace_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
|
-
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
-
};
|
|
17
|
-
run(): Promise<void>;
|
|
18
|
-
private confirm;
|
|
19
|
-
private loadCredentials;
|
|
20
|
-
}
|