@xano/cli 0.0.44 → 0.0.46

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 CHANGED
@@ -54,8 +54,8 @@ xano profile list
54
54
  xano profile list --details # Show masked tokens and settings
55
55
 
56
56
  # Get/set default profile
57
- xano profile get_default
58
- xano profile set_default myprofile
57
+ xano profile get
58
+ xano profile set myprofile
59
59
 
60
60
  # Edit a profile
61
61
  xano profile edit myprofile -w 123
@@ -113,15 +113,15 @@ xano workspace push ./my-workspace --no-env # Skip env vars
113
113
  xano workspace push ./my-workspace --truncate # Truncate tables before import
114
114
  xano workspace push ./my-workspace --no-sync-guids # Skip writing GUIDs back to local files
115
115
 
116
- # Import from a git repository to local files
117
- xano workspace git import ./output -r https://github.com/owner/repo
118
- xano workspace git import ./output -r https://github.com/owner/repo -b main
119
- xano workspace git import ./output -r https://github.com/owner/repo/tree/main/path/to/dir
120
- xano workspace git import ./output -r https://github.com/owner/repo/blob/main/file.xs
121
- xano workspace git import ./output -r git@github.com:owner/repo.git
122
- xano workspace git import ./output -r https://gitlab.com/owner/repo/-/tree/master/path
123
- xano workspace git import ./output -r https://github.com/owner/private-repo -t ghp_xxx
124
- xano workspace git import ./output -r https://github.com/owner/repo --path subdir
116
+ # Pull from a git repository to local files
117
+ xano workspace git pull ./output -r https://github.com/owner/repo
118
+ xano workspace git pull ./output -r https://github.com/owner/repo -b main
119
+ xano workspace git pull ./output -r https://github.com/owner/repo/tree/main/path/to/dir
120
+ xano workspace git pull ./output -r https://github.com/owner/repo/blob/main/file.xs
121
+ xano workspace git pull ./output -r git@github.com:owner/repo.git
122
+ xano workspace git pull ./output -r https://gitlab.com/owner/repo/-/tree/master/path
123
+ xano workspace git pull ./output -r https://github.com/owner/private-repo -t ghp_xxx
124
+ xano workspace git pull ./output -r https://github.com/owner/repo --path subdir
125
125
  ```
126
126
 
127
127
  ### Branches
@@ -470,6 +470,13 @@ profiles:
470
470
  default: default
471
471
  ```
472
472
 
473
+ ### Update
474
+
475
+ ```bash
476
+ # Update the CLI to the latest version
477
+ xano update
478
+ ```
479
+
473
480
  ## Scripts
474
481
 
475
482
  ### Bump Version
@@ -1,3 +1,4 @@
1
+ import { ExitPromptError } from '@inquirer/core';
1
2
  import { Command, Flags } from '@oclif/core';
2
3
  import inquirer from 'inquirer';
3
4
  import * as yaml from 'js-yaml';
@@ -82,7 +83,7 @@ Opening browser for Xano login at https://custom.xano.com...`,
82
83
  process.exit(0);
83
84
  }
84
85
  catch (error) {
85
- if (error instanceof Error && error.message.includes('User force closed the prompt')) {
86
+ if (error instanceof ExitPromptError) {
86
87
  this.log('Authentication cancelled.');
87
88
  return;
88
89
  }
@@ -233,7 +234,7 @@ Opening browser for Xano login at https://custom.xano.com...`,
233
234
  ],
234
235
  message: 'Select a branch',
235
236
  name: 'selectedBranch',
236
- type: 'list',
237
+ type: 'select',
237
238
  },
238
239
  ]);
239
240
  return selectedBranch || undefined;
@@ -247,7 +248,7 @@ Opening browser for Xano login at https://custom.xano.com...`,
247
248
  })),
248
249
  message: 'Select an instance',
249
250
  name: 'instanceId',
250
- type: 'list',
251
+ type: 'select',
251
252
  },
252
253
  ]);
253
254
  return instances.find((inst) => inst.id === instanceId);
@@ -264,7 +265,7 @@ Opening browser for Xano login at https://custom.xano.com...`,
264
265
  ],
265
266
  message: 'Select a workspace',
266
267
  name: 'selectedWorkspace',
267
- type: 'list',
268
+ type: 'select',
268
269
  },
269
270
  ]);
270
271
  if (!selectedWorkspace) {
@@ -442,7 +442,7 @@ Name: my_function
442
442
  choices,
443
443
  message: 'Select a function to edit:',
444
444
  name: 'functionId',
445
- type: 'list',
445
+ type: 'select',
446
446
  },
447
447
  ]);
448
448
  return answer.functionId;
@@ -257,7 +257,7 @@ function yo {
257
257
  choices,
258
258
  message: 'Select a function:',
259
259
  name: 'functionId',
260
- type: 'list',
260
+ type: 'select',
261
261
  },
262
262
  ]);
263
263
  return answer.functionId;
@@ -1,5 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- export default class ProfileGetDefault extends Command {
2
+ export default class ProfileGet extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  run(): Promise<void>;
@@ -3,24 +3,19 @@ import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
4
  import * as os from 'node:os';
5
5
  import * as path from 'node:path';
6
- export default class ProfileGetDefault extends Command {
6
+ export default class ProfileGet extends Command {
7
7
  static description = 'Get the current default profile name';
8
8
  static examples = [
9
- `$ xano profile:get-default
9
+ `$ xano profile get
10
10
  production
11
- `,
12
- `$ xano profile:get-default
13
- No default profile set
14
11
  `,
15
12
  ];
16
13
  async run() {
17
14
  const configDir = path.join(os.homedir(), '.xano');
18
15
  const credentialsPath = path.join(configDir, 'credentials.yaml');
19
- // Check if credentials file exists
20
16
  if (!fs.existsSync(credentialsPath)) {
21
17
  this.error(`Credentials file not found at ${credentialsPath}. No profiles exist.`);
22
18
  }
23
- // Read credentials file
24
19
  let credentials;
25
20
  try {
26
21
  const fileContent = fs.readFileSync(credentialsPath, 'utf8');
@@ -33,7 +28,6 @@ No default profile set
33
28
  catch (error) {
34
29
  this.error(`Failed to parse credentials file: ${error}`);
35
30
  }
36
- // Get and display the default profile
37
31
  if (credentials.default) {
38
32
  this.log(credentials.default);
39
33
  }
@@ -1,5 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- export default class ProfileSetDefault extends Command {
2
+ export default class ProfileSet extends Command {
3
3
  static args: {
4
4
  name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
5
  };
@@ -3,7 +3,7 @@ import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
4
  import * as os from 'node:os';
5
5
  import * as path from 'node:path';
6
- export default class ProfileSetDefault extends Command {
6
+ export default class ProfileSet extends Command {
7
7
  static args = {
8
8
  name: Args.string({
9
9
  description: 'Profile name to set as default',
@@ -12,22 +12,17 @@ export default class ProfileSetDefault extends Command {
12
12
  };
13
13
  static description = 'Set the default profile';
14
14
  static examples = [
15
- `$ xano profile:set-default production
15
+ `$ xano profile set production
16
16
  Default profile set to 'production'
17
- `,
18
- `$ xano profile:set-default staging
19
- Default profile set to 'staging'
20
17
  `,
21
18
  ];
22
19
  async run() {
23
- const { args } = await this.parse(ProfileSetDefault);
20
+ const { args } = await this.parse(ProfileSet);
24
21
  const configDir = path.join(os.homedir(), '.xano');
25
22
  const credentialsPath = path.join(configDir, 'credentials.yaml');
26
- // Check if credentials file exists
27
23
  if (!fs.existsSync(credentialsPath)) {
28
24
  this.error(`Credentials file not found at ${credentialsPath}. Create a profile first using 'profile:create'.`);
29
25
  }
30
- // Read existing credentials file
31
26
  let credentials;
32
27
  try {
33
28
  const fileContent = fs.readFileSync(credentialsPath, 'utf8');
@@ -40,13 +35,10 @@ Default profile set to 'staging'
40
35
  catch (error) {
41
36
  this.error(`Failed to parse credentials file: ${error}`);
42
37
  }
43
- // Check if profile exists
44
38
  if (!(args.name in credentials.profiles)) {
45
39
  this.error(`Profile '${args.name}' not found. Available profiles: ${Object.keys(credentials.profiles).join(', ')}`);
46
40
  }
47
- // Set the default profile
48
41
  credentials.default = args.name;
49
- // Write the updated credentials back to the file
50
42
  try {
51
43
  const yamlContent = yaml.dump(credentials, {
52
44
  indent: 2,
@@ -1,3 +1,4 @@
1
+ import { ExitPromptError } from '@inquirer/core';
1
2
  import { Command, Flags } from '@oclif/core';
2
3
  import inquirer from 'inquirer';
3
4
  import * as yaml from 'js-yaml';
@@ -73,7 +74,7 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
73
74
  })),
74
75
  message: 'Select an instance',
75
76
  name: 'instanceId',
76
- type: 'list',
77
+ type: 'select',
77
78
  },
78
79
  ]);
79
80
  const selectedInstance = instances.find((inst) => inst.id === instanceId);
@@ -120,7 +121,7 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
120
121
  ],
121
122
  message: 'Select a workspace (or skip to use default)',
122
123
  name: 'selectedWorkspace',
123
- type: 'list',
124
+ type: 'select',
124
125
  },
125
126
  ]);
126
127
  workspace = selectedWorkspace || undefined;
@@ -150,7 +151,7 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
150
151
  ],
151
152
  message: 'Select a branch',
152
153
  name: 'selectedBranch',
153
- type: 'list',
154
+ type: 'select',
154
155
  },
155
156
  ]);
156
157
  branch = selectedBranch || undefined;
@@ -170,7 +171,7 @@ Profile 'production' created successfully at ~/.xano/credentials.yaml
170
171
  this.log(`✓ Profile '${profileName}' created successfully!`);
171
172
  }
172
173
  catch (error) {
173
- if (error instanceof Error && error.message.includes('User force closed the prompt')) {
174
+ if (error instanceof ExitPromptError) {
174
175
  this.log('Wizard cancelled.');
175
176
  process.exit(0);
176
177
  }
@@ -0,0 +1,6 @@
1
+ import BaseCommand from '../../base-command.js';
2
+ export default class Update extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,26 @@
1
+ import { execSync } from 'node:child_process';
2
+ import BaseCommand from '../../base-command.js';
3
+ export default class Update extends BaseCommand {
4
+ static description = 'Update the Xano CLI to the latest version';
5
+ static examples = [
6
+ `$ xano update`,
7
+ ];
8
+ async run() {
9
+ const currentVersion = this.config.version;
10
+ this.log(`Current version: ${currentVersion}`);
11
+ this.log('Checking for updates...');
12
+ try {
13
+ const latest = execSync('npm view @xano/cli version', { encoding: 'utf8' }).trim();
14
+ if (latest === currentVersion) {
15
+ this.log(`Already up to date (${currentVersion})`);
16
+ return;
17
+ }
18
+ this.log(`Updating @xano/cli ${currentVersion} → ${latest}...`);
19
+ execSync('npm install -g @xano/cli@latest', { stdio: 'inherit' });
20
+ this.log(`Updated to ${latest}`);
21
+ }
22
+ catch (error) {
23
+ this.error(`Failed to update: ${error.message}`);
24
+ }
25
+ }
26
+ }
@@ -1,5 +1,5 @@
1
1
  import BaseCommand from '../../../../base-command.js';
2
- export default class GitImport extends BaseCommand {
2
+ export default class GitPull extends BaseCommand {
3
3
  static args: {
4
4
  directory: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
5
  };
@@ -6,22 +6,22 @@ import * as path from 'node:path';
6
6
  import snakeCase from 'lodash.snakecase';
7
7
  import BaseCommand from '../../../../base-command.js';
8
8
  import { parseDocument } from '../../../../utils/document-parser.js';
9
- export default class GitImport extends BaseCommand {
9
+ export default class GitPull extends BaseCommand {
10
10
  static args = {
11
11
  directory: Args.string({
12
12
  description: 'Output directory for imported files',
13
13
  required: true,
14
14
  }),
15
15
  };
16
- static description = 'Import XanoScript files from a git repository into a local directory';
16
+ static description = 'Pull XanoScript files from a git repository into a local directory';
17
17
  static examples = [
18
- `$ xano workspace git import ./output -r https://github.com/owner/repo`,
19
- `$ xano workspace git import ./output -r https://github.com/owner/repo/tree/main/path/to/dir`,
20
- `$ xano workspace git import ./output -r https://github.com/owner/repo/blob/main/path/to/file.xs`,
21
- `$ xano workspace git import ./output -r git@github.com:owner/repo.git`,
22
- `$ xano workspace git import ./output -r https://github.com/owner/private-repo -t ghp_xxx`,
23
- `$ xano workspace git import ./output -r https://gitlab.com/owner/repo/-/tree/master/path`,
24
- `$ xano workspace git import ./output -r https://gitlab.com/owner/repo -b main`,
18
+ `$ xano workspace git pull ./output -r https://github.com/owner/repo`,
19
+ `$ xano workspace git pull ./output -r https://github.com/owner/repo/tree/main/path/to/dir`,
20
+ `$ xano workspace git pull ./output -r https://github.com/owner/repo/blob/main/path/to/file.xs`,
21
+ `$ xano workspace git pull ./output -r git@github.com:owner/repo.git`,
22
+ `$ xano workspace git pull ./output -r https://github.com/owner/private-repo -t ghp_xxx`,
23
+ `$ xano workspace git pull ./output -r https://gitlab.com/owner/repo/-/tree/master/path`,
24
+ `$ xano workspace git pull ./output -r https://gitlab.com/owner/repo -b main`,
25
25
  ];
26
26
  static flags = {
27
27
  ...BaseCommand.baseFlags,
@@ -47,7 +47,7 @@ export default class GitImport extends BaseCommand {
47
47
  }),
48
48
  };
49
49
  async run() {
50
- const { args, flags } = await this.parse(GitImport);
50
+ const { args, flags } = await this.parse(GitPull);
51
51
  const token = flags.token || '';
52
52
  const outputDir = path.resolve(args.directory);
53
53
  // Normalize the URL to extract owner/repo/ref/path from various formats
@@ -56,7 +56,7 @@ export default class GitImport extends BaseCommand {
56
56
  const ref = flags.branch || repoInfo.ref;
57
57
  const subPath = flags.path || repoInfo.pathInRepo;
58
58
  // Create a temp directory for fetching
59
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'xano-git-import-'));
59
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'xano-git-pull-'));
60
60
  try {
61
61
  // Fetch repository contents
62
62
  let repoRoot;
@@ -114,7 +114,7 @@ export default class GitImport extends BaseCommand {
114
114
  writtenCount++;
115
115
  }
116
116
  const source = subPath ? `${flags.repo} (${subPath})` : flags.repo;
117
- this.log(`Imported ${writtenCount} documents from ${source} to ${args.directory}`);
117
+ this.log(`Pulled ${writtenCount} documents from ${source} to ${args.directory}`);
118
118
  }
119
119
  finally {
120
120
  // Clean up temp directory