@xano/cli 0.0.85 → 0.0.87

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
@@ -114,17 +114,17 @@ xano workspace pull ./my-workspace -b dev # Specific branch
114
114
  xano workspace pull ./my-workspace --env --records # Include env vars and table records
115
115
  xano workspace pull ./my-workspace --draft # Include draft changes
116
116
 
117
- # Push local files to workspace
117
+ # Push local files to workspace (only changed files by default)
118
118
  xano workspace push ./my-workspace
119
119
  xano workspace push ./my-workspace -b dev
120
+ xano workspace push ./my-workspace --sync # Full push — send all files, not just changed ones
121
+ xano workspace push ./my-workspace --sync --delete # Full push + delete remote objects not included
120
122
  xano workspace push ./my-workspace --dry-run # Preview changes without pushing
121
- xano workspace push ./my-workspace --partial # Push only changed files, workspace block not required
122
- xano workspace push ./my-workspace --delete # Delete objects not in the push
123
123
  xano workspace push ./my-workspace --records # Include table records
124
124
  xano workspace push ./my-workspace --env # Include environment variables
125
125
  xano workspace push ./my-workspace --truncate # Truncate tables before import
126
126
  xano workspace push ./my-workspace --no-transaction # Disable database transaction wrapping
127
- xano workspace push ./my-workspace --no-sync-guids # Skip writing GUIDs back to local files
127
+ xano workspace push ./my-workspace --no-guids # Skip writing GUIDs back to local files
128
128
  xano workspace push ./my-workspace --force # Skip preview and confirmation (for CI/CD)
129
129
 
130
130
  # Pull from a git repository to local files
@@ -10,9 +10,9 @@ export default class Push extends BaseCommand {
10
10
  delete: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
11
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
12
  env: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- partial: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ sync: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
14
  records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- 'sync-guids': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ guids: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
16
  transaction: import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
17
  truncate: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
18
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -12,19 +12,22 @@ export default class Push extends BaseCommand {
12
12
  required: true,
13
13
  }),
14
14
  };
15
- static description = 'Push local documents to a workspace. Shows a preview of changes before pushing unless --force is specified. Use --dry-run to preview only.';
15
+ static description = 'Push local documents to a workspace. By default, only changed files are pushed (partial mode). Use --sync to push all files. Shows a preview of changes before pushing unless --force is specified. Use --dry-run to preview only.';
16
16
  static examples = [
17
17
  `$ xano workspace push ./my-workspace
18
- Shows preview of changes, requires confirmation
18
+ Push only changed files (default partial mode)
19
+ `,
20
+ `$ xano workspace push ./my-workspace --sync
21
+ Push all files to the workspace
22
+ `,
23
+ `$ xano workspace push ./my-workspace --sync --delete
24
+ Push all files and delete remote objects not included
19
25
  `,
20
26
  `$ xano workspace push ./my-workspace --dry-run
21
27
  Preview changes without pushing
22
28
  `,
23
29
  `$ xano workspace push ./my-workspace --force
24
30
  Skip preview and push immediately (for CI/CD)
25
- `,
26
- `$ xano workspace push ./my-workspace --delete
27
- Shows preview including deletions, requires confirmation
28
31
  `,
29
32
  `$ xano workspace push ./output -w 40
30
33
  Pushed 15 documents from ./output
@@ -34,9 +37,6 @@ Pushed 58 documents from ./backup
34
37
  `,
35
38
  `$ xano workspace push ./my-workspace -b dev
36
39
  Pushed 42 documents from ./my-workspace
37
- `,
38
- `$ xano workspace push ./my-functions --partial
39
- Push some files without a workspace block (implies --no-delete)
40
40
  `,
41
41
  `$ xano workspace push ./my-workspace --no-records
42
42
  Push schema only, skip importing table records
@@ -57,7 +57,7 @@ Truncate all table records before importing
57
57
  }),
58
58
  delete: Flags.boolean({
59
59
  default: false,
60
- description: 'Delete workspace objects not included in the push',
60
+ description: 'Delete workspace objects not included in the push (requires --sync)',
61
61
  required: false,
62
62
  }),
63
63
  'dry-run': Flags.boolean({
@@ -70,9 +70,9 @@ Truncate all table records before importing
70
70
  description: 'Include environment variables in import',
71
71
  required: false,
72
72
  }),
73
- partial: Flags.boolean({
73
+ sync: Flags.boolean({
74
74
  default: false,
75
- description: 'Partial push — workspace block is not required, existing objects are kept (implies --no-delete)',
75
+ description: 'Full push — send all files, not just changed ones. Required for --delete.',
76
76
  required: false,
77
77
  }),
78
78
  records: Flags.boolean({
@@ -80,10 +80,10 @@ Truncate all table records before importing
80
80
  description: 'Include records in import',
81
81
  required: false,
82
82
  }),
83
- 'sync-guids': Flags.boolean({
83
+ guids: Flags.boolean({
84
84
  allowNo: true,
85
85
  default: true,
86
- description: 'Write server-assigned GUIDs back to local files (use --no-sync-guids to skip)',
86
+ description: 'Write server-assigned GUIDs back to local files (use --no-guids to skip)',
87
87
  required: false,
88
88
  }),
89
89
  transaction: Flags.boolean({
@@ -176,16 +176,17 @@ Truncate all table records before importing
176
176
  }
177
177
  // Determine branch from flag or profile
178
178
  const branch = flags.branch || profile.branch || '';
179
- if (flags.partial && flags.delete) {
180
- this.error('Cannot use --delete with --partial');
179
+ const isPartial = !flags.sync;
180
+ if (flags.delete && isPartial) {
181
+ this.error('Cannot use --delete without --sync');
181
182
  }
182
- const shouldDelete = flags.partial ? false : flags.delete;
183
+ const shouldDelete = isPartial ? false : flags.delete;
183
184
  // Construct the API URL
184
185
  const queryParams = new URLSearchParams({
185
186
  branch,
186
187
  delete: shouldDelete.toString(),
187
188
  env: flags.env.toString(),
188
- partial: flags.partial.toString(),
189
+ partial: isPartial.toString(),
189
190
  records: flags.records.toString(),
190
191
  transaction: flags.transaction.toString(),
191
192
  truncate: flags.truncate.toString(),
@@ -201,7 +202,7 @@ Truncate all table records before importing
201
202
  if (flags['dry-run'] || !flags.force) {
202
203
  const dryRunParams = new URLSearchParams(queryParams);
203
204
  // Request delete info in dry-run so we can show remote-only items (skip for partial)
204
- if (!flags.partial) {
205
+ if (!isPartial) {
205
206
  dryRunParams.set('delete', 'true');
206
207
  }
207
208
  const dryRunUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/multidoc/dry-run?${dryRunParams.toString()}`;
@@ -255,7 +256,7 @@ Truncate all table records before importing
255
256
  dryRunPreview = preview;
256
257
  // Check if the server returned a valid dry-run response
257
258
  if (preview && preview.summary) {
258
- this.renderPreview(preview, shouldDelete, workspaceId, flags.verbose, flags.partial);
259
+ this.renderPreview(preview, shouldDelete, workspaceId, flags.verbose, isPartial);
259
260
  // Check for critical errors that must block the push
260
261
  const criticalOps = preview.operations.filter((op) => op.details?.includes('exception:') || op.details?.includes('mvp:placeholder'));
261
262
  if (criticalOps.length > 0) {
@@ -374,7 +375,7 @@ Truncate all table records before importing
374
375
  }
375
376
  }
376
377
  // For partial pushes, filter to only changed documents
377
- if (flags.partial && dryRunPreview) {
378
+ if (isPartial && dryRunPreview) {
378
379
  const changedKeys = new Set(dryRunPreview.operations
379
380
  .filter((op) => op.action !== 'unchanged' && op.action !== 'delete' && op.action !== 'cascade_delete')
380
381
  .map((op) => `${op.type}:${op.name}`));
@@ -442,7 +443,7 @@ Truncate all table records before importing
442
443
  }
443
444
  }
444
445
  // Write GUIDs back to local files
445
- if (flags['sync-guids'] && guidMap.length > 0) {
446
+ if (flags.guids && guidMap.length > 0) {
446
447
  // Build a secondary lookup by type:name only (without verb/api_group)
447
448
  // for cases where the server omits those fields
448
449
  const baseKeyMap = new Map();
@@ -542,6 +543,9 @@ Truncate all table records before importing
542
543
  this.log('');
543
544
  const wsLabel = result.workspace_name ? `${result.workspace_name} (${workspaceId})` : `Workspace ${workspaceId}`;
544
545
  this.log(ux.colorize('bold', `=== Push Preview: ${wsLabel} ===`));
546
+ if (!partial) {
547
+ this.log(ux.colorize('red', ' --sync: all documents will be sent, including unchanged'));
548
+ }
545
549
  this.log('');
546
550
  for (const [type, counts] of Object.entries(result.summary)) {
547
551
  const label = typeLabels[type] || type;