@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 +4 -4
- package/dist/commands/workspace/push/index.d.ts +2 -2
- package/dist/commands/workspace/push/index.js +25 -21
- package/oclif.manifest.json +1503 -1503
- package/package.json +1 -1
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-
|
|
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
|
-
|
|
13
|
+
sync: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
73
|
+
sync: Flags.boolean({
|
|
74
74
|
default: false,
|
|
75
|
-
description: '
|
|
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
|
-
|
|
83
|
+
guids: Flags.boolean({
|
|
84
84
|
allowNo: true,
|
|
85
85
|
default: true,
|
|
86
|
-
description: 'Write server-assigned GUIDs back to local files (use --no-
|
|
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
|
-
|
|
180
|
-
|
|
179
|
+
const isPartial = !flags.sync;
|
|
180
|
+
if (flags.delete && isPartial) {
|
|
181
|
+
this.error('Cannot use --delete without --sync');
|
|
181
182
|
}
|
|
182
|
-
const shouldDelete =
|
|
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:
|
|
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 (!
|
|
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,
|
|
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 (
|
|
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
|
|
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;
|