@xano/cli 1.0.2-beta.1 → 1.0.2-beta.3

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.
Files changed (36) hide show
  1. package/README.md +9 -2
  2. package/dist/commands/branch/delete/index.js +1 -1
  3. package/dist/commands/branch/set_live/index.js +2 -2
  4. package/dist/commands/profile/delete/index.js +2 -2
  5. package/dist/commands/release/delete/index.js +1 -1
  6. package/dist/commands/release/deploy/index.js +3 -3
  7. package/dist/commands/release/import/index.js +1 -1
  8. package/dist/commands/release/push/index.js +1 -1
  9. package/dist/commands/sandbox/delete/index.js +2 -2
  10. package/dist/commands/sandbox/env/delete/index.js +1 -1
  11. package/dist/commands/sandbox/env/set_all/index.js +1 -1
  12. package/dist/commands/sandbox/license/set/index.js +1 -1
  13. package/dist/commands/sandbox/push/index.d.ts +0 -2
  14. package/dist/commands/sandbox/push/index.js +4 -26
  15. package/dist/commands/sandbox/reset/index.js +2 -2
  16. package/dist/commands/tenant/backup/delete/index.js +2 -2
  17. package/dist/commands/tenant/backup/restore/index.js +2 -2
  18. package/dist/commands/tenant/cluster/delete/index.js +2 -2
  19. package/dist/commands/tenant/cluster/license/set/index.js +1 -1
  20. package/dist/commands/tenant/create/index.js +1 -1
  21. package/dist/commands/tenant/delete/index.js +1 -1
  22. package/dist/commands/tenant/deploy_platform/index.js +1 -1
  23. package/dist/commands/tenant/deploy_release/index.js +1 -1
  24. package/dist/commands/tenant/edit/index.js +3 -3
  25. package/dist/commands/tenant/env/delete/index.js +1 -1
  26. package/dist/commands/tenant/env/set_all/index.js +1 -1
  27. package/dist/commands/tenant/license/set/index.js +1 -1
  28. package/dist/commands/tenant/push/index.js +1 -1
  29. package/dist/commands/workflow_test/delete/index.js +1 -1
  30. package/dist/commands/workspace/delete/index.js +1 -1
  31. package/dist/commands/workspace/edit/index.js +1 -1
  32. package/dist/commands/workspace/push/index.js +6 -6
  33. package/dist/utils/multidoc-push.d.ts +21 -0
  34. package/dist/utils/multidoc-push.js +44 -0
  35. package/oclif.manifest.json +2786 -2807
  36. package/package.json +1 -1
@@ -4,6 +4,16 @@ import * as fs from 'node:fs';
4
4
  import { join, relative } from 'node:path';
5
5
  import { buildDocumentKey, findFilesWithGuid, parseDocument } from './document-parser.js';
6
6
  import { checkReferences, checkTableIndexes } from './reference-checker.js';
7
+ // Minimum total operations before a workspace mismatch is treated as worth interrupting for.
8
+ // Small change sets (e.g., editing a single function) aren't worth a reset prompt.
9
+ export const WORKSPACE_MISMATCH_THRESHOLD = 10;
10
+ /**
11
+ * Sum all impactful operations in a dry-run summary. `deleted` is only counted when the
12
+ * caller actually intends to apply deletions (sync mode), matching what the user will see.
13
+ */
14
+ export function countSummaryChanges(summary, shouldDelete) {
15
+ return Object.values(summary).reduce((sum, c) => sum + c.created + c.updated + (shouldDelete ? c.deleted : 0) + c.truncated, 0);
16
+ }
7
17
  // ── File Collection ─────────────────────────────────────────────────────────
8
18
  /**
9
19
  * Recursively collect all .xs files from a directory, sorted for deterministic ordering.
@@ -211,6 +221,14 @@ function renderPreview(result, willDelete, target, verbose, partial, log) {
211
221
  }
212
222
  log('');
213
223
  }
224
+ export function findLocalWorkspaceName(entries) {
225
+ for (const entry of entries) {
226
+ const parsed = parseDocument(entry.content);
227
+ if (parsed?.type === 'workspace')
228
+ return parsed.name;
229
+ }
230
+ return null;
231
+ }
214
232
  // ── Confirmation ────────────────────────────────────────────────────────────
215
233
  export async function confirm(message) {
216
234
  const readline = await import('node:readline');
@@ -418,6 +436,32 @@ export async function executePush(ctx, target, flags) {
418
436
  if (flags['dry-run']) {
419
437
  return;
420
438
  }
439
+ // Warn when the sandbox currently holds a different workspace than the one being
440
+ // pushed and the change set is large enough that stale state is a real risk.
441
+ if (target.warnOnWorkspaceMismatch && preview.workspace_name) {
442
+ const localWorkspaceName = findLocalWorkspaceName(documentEntries);
443
+ const totalChanges = countSummaryChanges(preview.summary, shouldDelete);
444
+ if (localWorkspaceName &&
445
+ localWorkspaceName !== preview.workspace_name &&
446
+ totalChanges >= WORKSPACE_MISMATCH_THRESHOLD) {
447
+ log('');
448
+ log(ux.colorize('yellow', ux.colorize('bold', '=== Workspace Mismatch ===')));
449
+ log('');
450
+ log(ux.colorize('yellow', `Sandbox currently holds workspace "${preview.workspace_name}", but you're pushing "${localWorkspaceName}" with ${totalChanges} changes.`));
451
+ log(ux.colorize('yellow', 'Pushing on top of a different workspace can leave stale data behind. Run `xano sandbox reset` first to start clean.'));
452
+ log('');
453
+ if (process.stdin.isTTY) {
454
+ const proceed = await confirm('Continue with push anyway?');
455
+ if (!proceed) {
456
+ log('Push cancelled. Run `xano sandbox reset` then retry.');
457
+ return;
458
+ }
459
+ }
460
+ else {
461
+ command.error('Workspace mismatch detected in non-interactive mode. Run `xano sandbox reset` first to start clean.');
462
+ }
463
+ }
464
+ }
421
465
  // Confirm with user
422
466
  const hasDestructive = preview.operations.some((op) => (shouldDelete && (op.action === 'delete' || op.action === 'cascade_delete')) ||
423
467
  op.action === 'truncate' ||