@xano/cli 1.0.2-beta.4 → 1.0.2-beta.6
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 +87 -0
- package/dist/base-command.d.ts +21 -1
- package/dist/base-command.js +92 -6
- package/dist/commands/branch/create/index.d.ts +0 -1
- package/dist/commands/branch/create/index.js +1 -38
- package/dist/commands/branch/delete/index.d.ts +0 -1
- package/dist/commands/branch/delete/index.js +1 -39
- package/dist/commands/branch/edit/index.d.ts +0 -1
- package/dist/commands/branch/edit/index.js +1 -39
- package/dist/commands/branch/get/index.d.ts +0 -1
- package/dist/commands/branch/get/index.js +1 -39
- package/dist/commands/branch/list/index.d.ts +0 -1
- package/dist/commands/branch/list/index.js +1 -39
- package/dist/commands/branch/set_live/index.d.ts +0 -1
- package/dist/commands/branch/set_live/index.js +1 -39
- package/dist/commands/function/create/index.d.ts +0 -1
- package/dist/commands/function/create/index.js +1 -38
- package/dist/commands/function/edit/index.d.ts +0 -1
- package/dist/commands/function/edit/index.js +1 -37
- package/dist/commands/function/get/index.d.ts +0 -1
- package/dist/commands/function/get/index.js +1 -38
- package/dist/commands/function/list/index.d.ts +0 -1
- package/dist/commands/function/list/index.js +1 -39
- package/dist/commands/platform/get/index.d.ts +0 -1
- package/dist/commands/platform/get/index.js +1 -33
- package/dist/commands/platform/list/index.d.ts +0 -1
- package/dist/commands/platform/list/index.js +1 -33
- package/dist/commands/profile/use/index.d.ts +33 -0
- package/dist/commands/profile/use/index.js +179 -0
- package/dist/commands/profile/wizard/index.js +8 -2
- package/dist/commands/release/create/index.d.ts +0 -1
- package/dist/commands/release/create/index.js +1 -33
- package/dist/commands/release/delete/index.d.ts +0 -1
- package/dist/commands/release/delete/index.js +1 -33
- package/dist/commands/release/deploy/index.js +1 -12
- package/dist/commands/release/edit/index.d.ts +0 -1
- package/dist/commands/release/edit/index.js +1 -33
- package/dist/commands/release/export/index.d.ts +0 -1
- package/dist/commands/release/export/index.js +1 -31
- package/dist/commands/release/get/index.d.ts +0 -1
- package/dist/commands/release/get/index.js +1 -33
- package/dist/commands/release/import/index.d.ts +0 -1
- package/dist/commands/release/import/index.js +1 -32
- package/dist/commands/release/list/index.d.ts +0 -1
- package/dist/commands/release/list/index.js +1 -32
- package/dist/commands/release/pull/index.d.ts +0 -1
- package/dist/commands/release/pull/index.js +2 -38
- package/dist/commands/release/push/index.d.ts +0 -1
- package/dist/commands/release/push/index.js +1 -37
- package/dist/commands/static_host/build/create/index.d.ts +0 -1
- package/dist/commands/static_host/build/create/index.js +1 -39
- package/dist/commands/static_host/build/get/index.d.ts +0 -1
- package/dist/commands/static_host/build/get/index.js +1 -39
- package/dist/commands/static_host/build/list/index.d.ts +0 -1
- package/dist/commands/static_host/build/list/index.js +1 -39
- package/dist/commands/static_host/list/index.d.ts +0 -1
- package/dist/commands/static_host/list/index.js +1 -39
- package/dist/commands/tenant/backup/create/index.d.ts +0 -1
- package/dist/commands/tenant/backup/create/index.js +1 -33
- package/dist/commands/tenant/backup/delete/index.d.ts +0 -1
- package/dist/commands/tenant/backup/delete/index.js +1 -32
- package/dist/commands/tenant/backup/export/index.d.ts +0 -1
- package/dist/commands/tenant/backup/export/index.js +1 -31
- package/dist/commands/tenant/backup/import/index.d.ts +0 -1
- package/dist/commands/tenant/backup/import/index.js +1 -32
- package/dist/commands/tenant/backup/list/index.d.ts +0 -1
- package/dist/commands/tenant/backup/list/index.js +1 -33
- package/dist/commands/tenant/backup/restore/index.d.ts +0 -1
- package/dist/commands/tenant/backup/restore/index.js +1 -32
- package/dist/commands/tenant/cluster/create/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/create/index.js +1 -31
- package/dist/commands/tenant/cluster/delete/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/delete/index.js +1 -33
- package/dist/commands/tenant/cluster/edit/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/edit/index.js +1 -33
- package/dist/commands/tenant/cluster/get/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/get/index.js +1 -32
- package/dist/commands/tenant/cluster/license/get/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/license/get/index.js +1 -31
- package/dist/commands/tenant/cluster/license/set/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/license/set/index.js +1 -31
- package/dist/commands/tenant/cluster/list/index.d.ts +0 -1
- package/dist/commands/tenant/cluster/list/index.js +1 -32
- package/dist/commands/tenant/create/index.d.ts +0 -1
- package/dist/commands/tenant/create/index.js +1 -30
- package/dist/commands/tenant/delete/index.d.ts +0 -1
- package/dist/commands/tenant/delete/index.js +1 -33
- package/dist/commands/tenant/deploy_platform/index.d.ts +0 -1
- package/dist/commands/tenant/deploy_platform/index.js +1 -31
- package/dist/commands/tenant/deploy_release/index.d.ts +0 -1
- package/dist/commands/tenant/deploy_release/index.js +1 -32
- package/dist/commands/tenant/edit/index.d.ts +0 -1
- package/dist/commands/tenant/edit/index.js +1 -33
- package/dist/commands/tenant/env/delete/index.d.ts +0 -1
- package/dist/commands/tenant/env/delete/index.js +1 -32
- package/dist/commands/tenant/env/get/index.d.ts +0 -1
- package/dist/commands/tenant/env/get/index.js +1 -32
- package/dist/commands/tenant/env/get_all/index.d.ts +0 -1
- package/dist/commands/tenant/env/get_all/index.js +1 -30
- package/dist/commands/tenant/env/list/index.d.ts +0 -1
- package/dist/commands/tenant/env/list/index.js +1 -32
- package/dist/commands/tenant/env/set/index.d.ts +0 -1
- package/dist/commands/tenant/env/set/index.js +1 -32
- package/dist/commands/tenant/env/set_all/index.d.ts +0 -1
- package/dist/commands/tenant/env/set_all/index.js +1 -30
- package/dist/commands/tenant/get/index.d.ts +0 -1
- package/dist/commands/tenant/get/index.js +1 -32
- package/dist/commands/tenant/impersonate/index.d.ts +0 -1
- package/dist/commands/tenant/impersonate/index.js +1 -32
- package/dist/commands/tenant/license/get/index.d.ts +0 -1
- package/dist/commands/tenant/license/get/index.js +1 -31
- package/dist/commands/tenant/license/set/index.d.ts +0 -1
- package/dist/commands/tenant/license/set/index.js +1 -31
- package/dist/commands/tenant/list/index.d.ts +0 -1
- package/dist/commands/tenant/list/index.js +1 -32
- package/dist/commands/tenant/pull/index.d.ts +0 -1
- package/dist/commands/tenant/pull/index.js +1 -37
- package/dist/commands/tenant/unit_test/list/index.js +1 -12
- package/dist/commands/tenant/unit_test/run/index.js +1 -12
- package/dist/commands/tenant/unit_test/run_all/index.js +1 -12
- package/dist/commands/tenant/workflow_test/list/index.js +1 -12
- package/dist/commands/tenant/workflow_test/run/index.js +1 -12
- package/dist/commands/tenant/workflow_test/run_all/index.js +1 -12
- package/dist/commands/unit_test/list/index.d.ts +0 -1
- package/dist/commands/unit_test/list/index.js +1 -33
- package/dist/commands/unit_test/run/index.d.ts +0 -1
- package/dist/commands/unit_test/run/index.js +1 -33
- package/dist/commands/unit_test/run_all/index.d.ts +0 -1
- package/dist/commands/unit_test/run_all/index.js +1 -32
- package/dist/commands/workflow_test/delete/index.d.ts +0 -1
- package/dist/commands/workflow_test/delete/index.js +1 -33
- package/dist/commands/workflow_test/get/index.d.ts +0 -1
- package/dist/commands/workflow_test/get/index.js +1 -33
- package/dist/commands/workflow_test/list/index.d.ts +0 -1
- package/dist/commands/workflow_test/list/index.js +1 -33
- package/dist/commands/workflow_test/run/index.d.ts +0 -1
- package/dist/commands/workflow_test/run/index.js +1 -33
- package/dist/commands/workflow_test/run_all/index.d.ts +0 -1
- package/dist/commands/workflow_test/run_all/index.js +1 -32
- package/dist/commands/workspace/create/index.d.ts +0 -1
- package/dist/commands/workspace/create/index.js +1 -39
- package/dist/commands/workspace/delete/index.d.ts +0 -1
- package/dist/commands/workspace/delete/index.js +1 -39
- package/dist/commands/workspace/edit/index.d.ts +0 -1
- package/dist/commands/workspace/edit/index.js +1 -38
- package/dist/commands/workspace/get/index.d.ts +0 -1
- package/dist/commands/workspace/get/index.js +1 -38
- package/dist/commands/workspace/list/index.d.ts +0 -1
- package/dist/commands/workspace/list/index.js +1 -38
- package/dist/commands/workspace/pull/index.d.ts +0 -1
- package/dist/commands/workspace/pull/index.js +1 -37
- package/dist/utils/local-config.d.ts +43 -0
- package/dist/utils/local-config.js +88 -0
- package/oclif.manifest.json +2153 -2066
- package/package.json +1 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
2
|
import BaseCommand from '../../../base-command.js';
|
|
5
3
|
export default class BranchSetLive extends BaseCommand {
|
|
6
4
|
static args = {
|
|
@@ -50,23 +48,7 @@ Branch 'v1' is now live
|
|
|
50
48
|
};
|
|
51
49
|
async run() {
|
|
52
50
|
const { args, flags } = await this.parse(BranchSetLive);
|
|
53
|
-
|
|
54
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
55
|
-
// Load credentials
|
|
56
|
-
const credentials = this.loadCredentials();
|
|
57
|
-
// Get the profile configuration
|
|
58
|
-
if (!(profileName in credentials.profiles)) {
|
|
59
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
60
|
-
`Create a profile using 'xano profile create'`);
|
|
61
|
-
}
|
|
62
|
-
const profile = credentials.profiles[profileName];
|
|
63
|
-
// Validate required fields
|
|
64
|
-
if (!profile.instance_origin) {
|
|
65
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
66
|
-
}
|
|
67
|
-
if (!profile.access_token) {
|
|
68
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
69
|
-
}
|
|
51
|
+
const { profile } = this.resolveProfile(flags);
|
|
70
52
|
// Get workspace ID from flag or profile
|
|
71
53
|
const workspaceId = flags.workspace || profile.workspace;
|
|
72
54
|
if (!workspaceId) {
|
|
@@ -129,24 +111,4 @@ Branch 'v1' is now live
|
|
|
129
111
|
});
|
|
130
112
|
});
|
|
131
113
|
}
|
|
132
|
-
loadCredentials() {
|
|
133
|
-
const credentialsPath = this.getCredentialsPath();
|
|
134
|
-
// Check if credentials file exists
|
|
135
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
136
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
137
|
-
`Create a profile using 'xano profile create'`);
|
|
138
|
-
}
|
|
139
|
-
// Read credentials file
|
|
140
|
-
try {
|
|
141
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
142
|
-
const parsed = yaml.load(fileContent);
|
|
143
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
144
|
-
this.error('Credentials file has invalid format.');
|
|
145
|
-
}
|
|
146
|
-
return parsed;
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
114
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
2
|
import { execSync } from 'node:child_process';
|
|
4
3
|
import * as fs from 'node:fs';
|
|
5
4
|
import * as os from 'node:os';
|
|
@@ -75,23 +74,7 @@ Name: my_function
|
|
|
75
74
|
};
|
|
76
75
|
async run() {
|
|
77
76
|
const { flags } = await this.parse(FunctionCreate);
|
|
78
|
-
|
|
79
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
80
|
-
// Load credentials
|
|
81
|
-
const credentials = this.loadCredentials();
|
|
82
|
-
// Get the profile configuration
|
|
83
|
-
if (!(profileName in credentials.profiles)) {
|
|
84
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
85
|
-
`Create a profile using 'xano profile:create'`);
|
|
86
|
-
}
|
|
87
|
-
const profile = credentials.profiles[profileName];
|
|
88
|
-
// Validate required fields
|
|
89
|
-
if (!profile.instance_origin) {
|
|
90
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
91
|
-
}
|
|
92
|
-
if (!profile.access_token) {
|
|
93
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
94
|
-
}
|
|
77
|
+
const { profile, profileName } = this.resolveProfile(flags);
|
|
95
78
|
// Determine workspace_id from flag or profile
|
|
96
79
|
let workspaceId;
|
|
97
80
|
if (flags.workspace) {
|
|
@@ -240,26 +223,6 @@ Name: my_function
|
|
|
240
223
|
}
|
|
241
224
|
return tmpFile;
|
|
242
225
|
}
|
|
243
|
-
loadCredentials() {
|
|
244
|
-
const credentialsPath = this.getCredentialsPath();
|
|
245
|
-
// Check if credentials file exists
|
|
246
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
247
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
248
|
-
`Create a profile using 'xano profile:create'`);
|
|
249
|
-
}
|
|
250
|
-
// Read credentials file
|
|
251
|
-
try {
|
|
252
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
253
|
-
const parsed = yaml.load(fileContent);
|
|
254
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
255
|
-
this.error('Credentials file has invalid format.');
|
|
256
|
-
}
|
|
257
|
-
return parsed;
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
226
|
async readStdin() {
|
|
264
227
|
return new Promise((resolve, reject) => {
|
|
265
228
|
const chunks = [];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
|
-
import * as yaml from 'js-yaml';
|
|
4
3
|
import { execSync } from 'node:child_process';
|
|
5
4
|
import * as fs from 'node:fs';
|
|
6
5
|
import * as os from 'node:os';
|
|
@@ -102,23 +101,7 @@ Name: my_function
|
|
|
102
101
|
};
|
|
103
102
|
async run() {
|
|
104
103
|
const { args, flags } = await this.parse(FunctionEdit);
|
|
105
|
-
|
|
106
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
107
|
-
// Load credentials
|
|
108
|
-
const credentials = this.loadCredentials();
|
|
109
|
-
// Get the profile configuration
|
|
110
|
-
if (!(profileName in credentials.profiles)) {
|
|
111
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
112
|
-
`Create a profile using 'xano profile:create'`);
|
|
113
|
-
}
|
|
114
|
-
const profile = credentials.profiles[profileName];
|
|
115
|
-
// Validate required fields
|
|
116
|
-
if (!profile.instance_origin) {
|
|
117
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
118
|
-
}
|
|
119
|
-
if (!profile.access_token) {
|
|
120
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
121
|
-
}
|
|
104
|
+
const { profile, profileName } = this.resolveProfile(flags);
|
|
122
105
|
// Validate flag combinations
|
|
123
106
|
if (flags.edit && !flags.file) {
|
|
124
107
|
this.error('The --edit flag requires --file to be specified');
|
|
@@ -368,25 +351,6 @@ Name: my_function
|
|
|
368
351
|
throw error;
|
|
369
352
|
}
|
|
370
353
|
}
|
|
371
|
-
loadCredentials() {
|
|
372
|
-
const credentialsPath = this.getCredentialsPath();
|
|
373
|
-
// Check if credentials file exists
|
|
374
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
375
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile:create'`);
|
|
376
|
-
}
|
|
377
|
-
// Read credentials file
|
|
378
|
-
try {
|
|
379
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
380
|
-
const parsed = yaml.load(fileContent);
|
|
381
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
382
|
-
this.error('Credentials file has invalid format.');
|
|
383
|
-
}
|
|
384
|
-
return parsed;
|
|
385
|
-
}
|
|
386
|
-
catch (error) {
|
|
387
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
354
|
async promptForFunctionId(profile, workspaceId) {
|
|
391
355
|
try {
|
|
392
356
|
// Fetch list of functions
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
|
-
import * as yaml from 'js-yaml';
|
|
4
|
-
import * as fs from 'node:fs';
|
|
5
3
|
import BaseCommand, { buildUserAgent } from '../../../base-command.js';
|
|
6
4
|
export default class FunctionGet extends BaseCommand {
|
|
7
5
|
static args = {
|
|
@@ -76,23 +74,7 @@ function yo {
|
|
|
76
74
|
};
|
|
77
75
|
async run() {
|
|
78
76
|
const { args, flags } = await this.parse(FunctionGet);
|
|
79
|
-
|
|
80
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
81
|
-
// Load credentials
|
|
82
|
-
const credentials = this.loadCredentials();
|
|
83
|
-
// Get the profile configuration
|
|
84
|
-
if (!(profileName in credentials.profiles)) {
|
|
85
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
86
|
-
`Create a profile using 'xano profile:create'`);
|
|
87
|
-
}
|
|
88
|
-
const profile = credentials.profiles[profileName];
|
|
89
|
-
// Validate required fields
|
|
90
|
-
if (!profile.instance_origin) {
|
|
91
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
92
|
-
}
|
|
93
|
-
if (!profile.access_token) {
|
|
94
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
95
|
-
}
|
|
77
|
+
const { profile, profileName } = this.resolveProfile(flags);
|
|
96
78
|
// Determine workspace_id from flag or profile
|
|
97
79
|
let workspaceId;
|
|
98
80
|
if (flags.workspace) {
|
|
@@ -182,25 +164,6 @@ function yo {
|
|
|
182
164
|
}
|
|
183
165
|
}
|
|
184
166
|
}
|
|
185
|
-
loadCredentials() {
|
|
186
|
-
const credentialsPath = this.getCredentialsPath();
|
|
187
|
-
// Check if credentials file exists
|
|
188
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
189
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile:create'`);
|
|
190
|
-
}
|
|
191
|
-
// Read credentials file
|
|
192
|
-
try {
|
|
193
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
194
|
-
const parsed = yaml.load(fileContent);
|
|
195
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
196
|
-
this.error('Credentials file has invalid format.');
|
|
197
|
-
}
|
|
198
|
-
return parsed;
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
167
|
async promptForFunctionId(profile, workspaceId) {
|
|
205
168
|
try {
|
|
206
169
|
// Fetch list of functions
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
2
|
import BaseCommand from '../../../base-command.js';
|
|
5
3
|
export default class FunctionList extends BaseCommand {
|
|
6
4
|
static args = {};
|
|
@@ -82,23 +80,7 @@ Available functions:
|
|
|
82
80
|
};
|
|
83
81
|
async run() {
|
|
84
82
|
const { flags } = await this.parse(FunctionList);
|
|
85
|
-
|
|
86
|
-
const profileName = flags.profile || this.getDefaultProfile();
|
|
87
|
-
// Load credentials
|
|
88
|
-
const credentials = this.loadCredentials();
|
|
89
|
-
// Get the profile configuration
|
|
90
|
-
if (!(profileName in credentials.profiles)) {
|
|
91
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
92
|
-
`Create a profile using 'xano profile:create'`);
|
|
93
|
-
}
|
|
94
|
-
const profile = credentials.profiles[profileName];
|
|
95
|
-
// Validate required fields
|
|
96
|
-
if (!profile.instance_origin) {
|
|
97
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
98
|
-
}
|
|
99
|
-
if (!profile.access_token) {
|
|
100
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
101
|
-
}
|
|
83
|
+
const { profile, profileName } = this.resolveProfile(flags);
|
|
102
84
|
// Determine workspace_id from flag or profile
|
|
103
85
|
let workspaceId;
|
|
104
86
|
if (flags.workspace) {
|
|
@@ -182,24 +164,4 @@ Available functions:
|
|
|
182
164
|
}
|
|
183
165
|
}
|
|
184
166
|
}
|
|
185
|
-
loadCredentials() {
|
|
186
|
-
const credentialsPath = this.getCredentialsPath();
|
|
187
|
-
// Check if credentials file exists
|
|
188
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
189
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
190
|
-
`Create a profile using 'xano profile:create'`);
|
|
191
|
-
}
|
|
192
|
-
// Read credentials file
|
|
193
|
-
try {
|
|
194
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
195
|
-
const parsed = yaml.load(fileContent);
|
|
196
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
197
|
-
this.error('Credentials file has invalid format.');
|
|
198
|
-
}
|
|
199
|
-
return parsed;
|
|
200
|
-
}
|
|
201
|
-
catch (error) {
|
|
202
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
167
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
2
|
import BaseCommand from '../../../base-command.js';
|
|
5
3
|
export default class PlatformGet extends BaseCommand {
|
|
6
4
|
static args = {
|
|
@@ -43,19 +41,7 @@ Platform ID: 23629
|
|
|
43
41
|
};
|
|
44
42
|
async run() {
|
|
45
43
|
const { args, flags } = await this.parse(PlatformGet);
|
|
46
|
-
const
|
|
47
|
-
const credentials = this.loadCredentials();
|
|
48
|
-
if (!(profileName in credentials.profiles)) {
|
|
49
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
50
|
-
`Create a profile using 'xano profile create'`);
|
|
51
|
-
}
|
|
52
|
-
const profile = credentials.profiles[profileName];
|
|
53
|
-
if (!profile.instance_origin) {
|
|
54
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
55
|
-
}
|
|
56
|
-
if (!profile.access_token) {
|
|
57
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
58
|
-
}
|
|
44
|
+
const { profile } = this.resolveProfile(flags);
|
|
59
45
|
const platformId = args.platform_id;
|
|
60
46
|
const apiUrl = `${profile.instance_origin}/api:meta/platform/${platformId}`;
|
|
61
47
|
try {
|
|
@@ -102,22 +88,4 @@ Platform ID: 23629
|
|
|
102
88
|
}
|
|
103
89
|
}
|
|
104
90
|
}
|
|
105
|
-
loadCredentials() {
|
|
106
|
-
const credentialsPath = this.getCredentialsPath();
|
|
107
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
108
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
109
|
-
`Create a profile using 'xano profile create'`);
|
|
110
|
-
}
|
|
111
|
-
try {
|
|
112
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
113
|
-
const parsed = yaml.load(fileContent);
|
|
114
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
115
|
-
this.error('Credentials file has invalid format.');
|
|
116
|
-
}
|
|
117
|
-
return parsed;
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
91
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
-
import * as yaml from 'js-yaml';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
2
|
import BaseCommand from '../../../base-command.js';
|
|
5
3
|
export default class PlatformList extends BaseCommand {
|
|
6
4
|
static description = 'List all platforms';
|
|
@@ -23,19 +21,7 @@ Platforms:
|
|
|
23
21
|
};
|
|
24
22
|
async run() {
|
|
25
23
|
const { flags } = await this.parse(PlatformList);
|
|
26
|
-
const
|
|
27
|
-
const credentials = this.loadCredentials();
|
|
28
|
-
if (!(profileName in credentials.profiles)) {
|
|
29
|
-
this.error(`Profile '${profileName}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}\n` +
|
|
30
|
-
`Create a profile using 'xano profile create'`);
|
|
31
|
-
}
|
|
32
|
-
const profile = credentials.profiles[profileName];
|
|
33
|
-
if (!profile.instance_origin) {
|
|
34
|
-
this.error(`Profile '${profileName}' is missing instance_origin`);
|
|
35
|
-
}
|
|
36
|
-
if (!profile.access_token) {
|
|
37
|
-
this.error(`Profile '${profileName}' is missing access_token`);
|
|
38
|
-
}
|
|
24
|
+
const { profile } = this.resolveProfile(flags);
|
|
39
25
|
const apiUrl = `${profile.instance_origin}/api:meta/platform`;
|
|
40
26
|
try {
|
|
41
27
|
const response = await this.verboseFetch(apiUrl, {
|
|
@@ -89,22 +75,4 @@ Platforms:
|
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
77
|
}
|
|
92
|
-
loadCredentials() {
|
|
93
|
-
const credentialsPath = this.getCredentialsPath();
|
|
94
|
-
if (!fs.existsSync(credentialsPath)) {
|
|
95
|
-
this.error(`Credentials file not found at ${credentialsPath}\n` +
|
|
96
|
-
`Create a profile using 'xano profile create'`);
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
100
|
-
const parsed = yaml.load(fileContent);
|
|
101
|
-
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
102
|
-
this.error('Credentials file has invalid format.');
|
|
103
|
-
}
|
|
104
|
-
return parsed;
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
this.error(`Failed to parse credentials file: ${error}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
78
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { type LocalProfileConfig } from '../../../utils/local-config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Ensure `entry` exists as its own line in a .gitignore.
|
|
5
|
+
* Returns the (possibly unchanged) content and whether a write is needed.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ensureGitignoreEntry(existing: null | string, entry: string): {
|
|
8
|
+
changed: boolean;
|
|
9
|
+
content: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Build a self-documenting profile.yaml string from a LocalProfileConfig.
|
|
13
|
+
* Set fields are emitted uncommented; unset fields appear as commented placeholders.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildProfileYaml(config: LocalProfileConfig): string;
|
|
16
|
+
export default class ProfileUse extends Command {
|
|
17
|
+
static args: {
|
|
18
|
+
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
19
|
+
};
|
|
20
|
+
static description: string;
|
|
21
|
+
static examples: string[];
|
|
22
|
+
static flags: {
|
|
23
|
+
account_origin: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
|
+
branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
25
|
+
config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
26
|
+
gitignore: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
instance_origin: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
28
|
+
workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
29
|
+
};
|
|
30
|
+
run(): Promise<void>;
|
|
31
|
+
private assertProfileExists;
|
|
32
|
+
private handleGitignore;
|
|
33
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import * as yaml from 'js-yaml';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
import { resolveCredentialsPath } from '../../../base-command.js';
|
|
7
|
+
import { LOCAL_PROFILE_FILENAME } from '../../../utils/local-config.js';
|
|
8
|
+
/**
|
|
9
|
+
* Ensure `entry` exists as its own line in a .gitignore.
|
|
10
|
+
* Returns the (possibly unchanged) content and whether a write is needed.
|
|
11
|
+
*/
|
|
12
|
+
export function ensureGitignoreEntry(existing, entry) {
|
|
13
|
+
const lines = existing ? existing.split('\n').map((line) => line.trim()) : [];
|
|
14
|
+
if (lines.includes(entry)) {
|
|
15
|
+
return { changed: false, content: existing ?? '' };
|
|
16
|
+
}
|
|
17
|
+
const base = existing && !existing.endsWith('\n') ? existing + '\n' : existing ?? '';
|
|
18
|
+
return { changed: true, content: `${base}${entry}\n` };
|
|
19
|
+
}
|
|
20
|
+
const OVERRIDE_FIELDS = [
|
|
21
|
+
{ key: 'workspace', placeholder: '123' },
|
|
22
|
+
{ key: 'instance_origin', placeholder: 'https://your-instance.xano.io' },
|
|
23
|
+
{ key: 'account_origin', placeholder: 'https://app.xano.com' },
|
|
24
|
+
{ key: 'branch', placeholder: 'main' },
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* Build a self-documenting profile.yaml string from a LocalProfileConfig.
|
|
28
|
+
* Set fields are emitted uncommented; unset fields appear as commented placeholders.
|
|
29
|
+
*/
|
|
30
|
+
export function buildProfileYaml(config) {
|
|
31
|
+
const lines = [
|
|
32
|
+
'# Xano project-local profile — pins this project to a profile in ~/.xano/credentials.yaml.',
|
|
33
|
+
'# No secrets here: the access token always comes from credentials.yaml.',
|
|
34
|
+
'# Precedence: an explicit -p/--profile or XANO_PROFILE overrides this file entirely.',
|
|
35
|
+
'',
|
|
36
|
+
'# Profile to use (a profile name from ~/.xano/credentials.yaml):',
|
|
37
|
+
`profile: ${config.profile}`,
|
|
38
|
+
'',
|
|
39
|
+
'# Optional per-project overrides — uncomment and edit any you need:',
|
|
40
|
+
];
|
|
41
|
+
for (const { key, placeholder } of OVERRIDE_FIELDS) {
|
|
42
|
+
const value = config[key];
|
|
43
|
+
lines.push(value === undefined ? `# ${key}: ${placeholder}` : `${key}: ${value}`);
|
|
44
|
+
}
|
|
45
|
+
lines.push('');
|
|
46
|
+
return lines.join('\n');
|
|
47
|
+
}
|
|
48
|
+
export default class ProfileUse extends Command {
|
|
49
|
+
static args = {
|
|
50
|
+
name: Args.string({
|
|
51
|
+
description: 'Profile name (from credentials.yaml) to pin for this project',
|
|
52
|
+
required: true,
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
static description = 'Pin a profile for the current project by writing a local profile.yaml. ' +
|
|
56
|
+
'When present, the CLI uses this profile (and any overrides) instead of the default, ' +
|
|
57
|
+
'unless -p/--profile or XANO_PROFILE is set.';
|
|
58
|
+
static examples = [
|
|
59
|
+
`$ xano profile use staging
|
|
60
|
+
Wrote profile.yaml pinning profile 'staging'
|
|
61
|
+
`,
|
|
62
|
+
`$ xano profile use staging -w 110
|
|
63
|
+
Wrote profile.yaml pinning profile 'staging' (workspace 110)
|
|
64
|
+
`,
|
|
65
|
+
`$ xano profile use staging -w 110 --gitignore
|
|
66
|
+
Wrote profile.yaml pinning profile 'staging' (workspace 110)
|
|
67
|
+
Added profile.yaml to .gitignore
|
|
68
|
+
`,
|
|
69
|
+
];
|
|
70
|
+
static flags = {
|
|
71
|
+
// eslint-disable-next-line camelcase
|
|
72
|
+
account_origin: Flags.string({
|
|
73
|
+
char: 'a',
|
|
74
|
+
description: 'Override account origin for this project',
|
|
75
|
+
required: false,
|
|
76
|
+
}),
|
|
77
|
+
branch: Flags.string({
|
|
78
|
+
char: 'b',
|
|
79
|
+
description: 'Override branch for this project',
|
|
80
|
+
required: false,
|
|
81
|
+
}),
|
|
82
|
+
config: Flags.string({
|
|
83
|
+
char: 'c',
|
|
84
|
+
description: 'Path to credentials file (default: ~/.xano/credentials.yaml)',
|
|
85
|
+
env: 'XANO_CONFIG',
|
|
86
|
+
required: false,
|
|
87
|
+
}),
|
|
88
|
+
gitignore: Flags.boolean({
|
|
89
|
+
allowNo: true,
|
|
90
|
+
description: 'Add (or skip adding) profile.yaml to .gitignore without prompting',
|
|
91
|
+
required: false,
|
|
92
|
+
}),
|
|
93
|
+
// eslint-disable-next-line camelcase
|
|
94
|
+
instance_origin: Flags.string({
|
|
95
|
+
char: 'i',
|
|
96
|
+
description: 'Override instance origin for this project',
|
|
97
|
+
required: false,
|
|
98
|
+
}),
|
|
99
|
+
workspace: Flags.string({
|
|
100
|
+
char: 'w',
|
|
101
|
+
description: 'Override workspace for this project',
|
|
102
|
+
required: false,
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
async run() {
|
|
106
|
+
const { args, flags } = await this.parse(ProfileUse);
|
|
107
|
+
this.assertProfileExists(args.name, flags.config);
|
|
108
|
+
const config = { profile: args.name };
|
|
109
|
+
if (flags.workspace)
|
|
110
|
+
config.workspace = flags.workspace;
|
|
111
|
+
// eslint-disable-next-line camelcase
|
|
112
|
+
if (flags.instance_origin)
|
|
113
|
+
config.instance_origin = flags.instance_origin;
|
|
114
|
+
// eslint-disable-next-line camelcase
|
|
115
|
+
if (flags.account_origin)
|
|
116
|
+
config.account_origin = flags.account_origin;
|
|
117
|
+
if (flags.branch)
|
|
118
|
+
config.branch = flags.branch;
|
|
119
|
+
const filePath = resolve(process.cwd(), LOCAL_PROFILE_FILENAME);
|
|
120
|
+
if (fs.existsSync(filePath)) {
|
|
121
|
+
this.warn(`Overwriting existing ${LOCAL_PROFILE_FILENAME}`);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
fs.writeFileSync(filePath, buildProfileYaml(config), 'utf8');
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
this.error(`Failed to write ${LOCAL_PROFILE_FILENAME}: ${error}`);
|
|
128
|
+
}
|
|
129
|
+
const workspaceNote = flags.workspace ? ` (workspace ${flags.workspace})` : '';
|
|
130
|
+
this.log(`Wrote ${LOCAL_PROFILE_FILENAME} pinning profile '${args.name}'${workspaceNote}`);
|
|
131
|
+
await this.handleGitignore(flags.gitignore);
|
|
132
|
+
}
|
|
133
|
+
assertProfileExists(name, configPath) {
|
|
134
|
+
const credentialsPath = resolveCredentialsPath(configPath);
|
|
135
|
+
if (!fs.existsSync(credentialsPath)) {
|
|
136
|
+
this.error(`Credentials file not found at ${credentialsPath}. Create a profile first using 'xano auth'.`);
|
|
137
|
+
}
|
|
138
|
+
let parsed;
|
|
139
|
+
try {
|
|
140
|
+
parsed = yaml.load(fs.readFileSync(credentialsPath, 'utf8'));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
this.error(`Failed to parse credentials file: ${error}`);
|
|
144
|
+
}
|
|
145
|
+
if (!parsed || typeof parsed !== 'object' || !('profiles' in parsed)) {
|
|
146
|
+
this.error('Credentials file has invalid format.');
|
|
147
|
+
}
|
|
148
|
+
if (!(name in parsed.profiles)) {
|
|
149
|
+
this.error(`Profile '${name}' not found. Available profiles: ${Object.keys(parsed.profiles).join(', ')}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async handleGitignore(flag) {
|
|
153
|
+
const gitignorePath = resolve(process.cwd(), '.gitignore');
|
|
154
|
+
const existing = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf8') : null;
|
|
155
|
+
// If profile.yaml is already in .gitignore, no action needed regardless of flag.
|
|
156
|
+
const alreadyIgnored = !ensureGitignoreEntry(existing, LOCAL_PROFILE_FILENAME).changed;
|
|
157
|
+
if (alreadyIgnored) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
let shouldAdd = flag;
|
|
161
|
+
if (shouldAdd === undefined) {
|
|
162
|
+
const { add } = await inquirer.prompt([
|
|
163
|
+
{
|
|
164
|
+
default: false,
|
|
165
|
+
message: `Add ${LOCAL_PROFILE_FILENAME} to .gitignore?`,
|
|
166
|
+
name: 'add',
|
|
167
|
+
type: 'confirm',
|
|
168
|
+
},
|
|
169
|
+
]);
|
|
170
|
+
shouldAdd = add;
|
|
171
|
+
}
|
|
172
|
+
if (!shouldAdd) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const { content } = ensureGitignoreEntry(existing, LOCAL_PROFILE_FILENAME);
|
|
176
|
+
fs.writeFileSync(gitignorePath, content, 'utf8');
|
|
177
|
+
this.log(`Added ${LOCAL_PROFILE_FILENAME} to .gitignore`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -217,7 +217,10 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
|
|
|
217
217
|
// Transform API response to Branch format
|
|
218
218
|
// Assuming the API returns an array or object with branches
|
|
219
219
|
if (Array.isArray(data)) {
|
|
220
|
-
return data
|
|
220
|
+
return data
|
|
221
|
+
.filter((br) => !br.backup)
|
|
222
|
+
.map((br) => ({
|
|
223
|
+
backup: br.backup,
|
|
221
224
|
id: br.id || br.label,
|
|
222
225
|
label: br.label,
|
|
223
226
|
}));
|
|
@@ -226,7 +229,10 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
|
|
|
226
229
|
if (data && typeof data === 'object') {
|
|
227
230
|
const branches = data.branches || data.data || [];
|
|
228
231
|
if (Array.isArray(branches)) {
|
|
229
|
-
return branches
|
|
232
|
+
return branches
|
|
233
|
+
.filter((br) => !br.backup)
|
|
234
|
+
.map((br) => ({
|
|
235
|
+
backup: br.backup,
|
|
230
236
|
id: br.id || br.name,
|
|
231
237
|
label: br.label,
|
|
232
238
|
}));
|