@xano/cli 0.0.79 → 0.0.80-beta.0
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/dist/commands/tenant/push/index.d.ts +1 -0
- package/dist/commands/tenant/push/index.js +7 -0
- package/dist/commands/update/index.js +2 -0
- package/dist/commands/workspace/push/index.d.ts +1 -0
- package/dist/commands/workspace/push/index.js +28 -1
- package/dist/update-check.d.ts +1 -0
- package/dist/update-check.js +23 -1
- package/oclif.manifest.json +1580 -1566
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ export default class Push extends BaseCommand {
|
|
|
9
9
|
env: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
11
|
tenant: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
transaction: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
13
|
truncate: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
14
|
workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -50,6 +50,12 @@ Truncate all table records before importing
|
|
|
50
50
|
description: 'Tenant name to push to',
|
|
51
51
|
required: true,
|
|
52
52
|
}),
|
|
53
|
+
transaction: Flags.boolean({
|
|
54
|
+
allowNo: true,
|
|
55
|
+
default: true,
|
|
56
|
+
description: 'Wrap import in a database transaction (use --no-transaction for debugging purposes)',
|
|
57
|
+
required: false,
|
|
58
|
+
}),
|
|
53
59
|
truncate: Flags.boolean({
|
|
54
60
|
default: false,
|
|
55
61
|
description: 'Truncate all table records before importing',
|
|
@@ -157,6 +163,7 @@ Truncate all table records before importing
|
|
|
157
163
|
const queryParams = new URLSearchParams({
|
|
158
164
|
env: flags.env.toString(),
|
|
159
165
|
records: flags.records.toString(),
|
|
166
|
+
transaction: flags.transaction.toString(),
|
|
160
167
|
truncate: flags.truncate.toString(),
|
|
161
168
|
});
|
|
162
169
|
const apiUrl = `${profile.instance_origin}/api:meta/workspace/${workspaceId}/tenant/${tenantName}/multidoc?${queryParams.toString()}`;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import BaseCommand from '../../base-command.js';
|
|
4
|
+
import { clearUpdateCache } from '../../update-check.js';
|
|
4
5
|
export default class Update extends BaseCommand {
|
|
5
6
|
static description = 'Update the Xano CLI to the latest version';
|
|
6
7
|
static examples = [`$ xano update`, `$ xano update --check`, `$ xano update --beta`];
|
|
@@ -31,6 +32,7 @@ export default class Update extends BaseCommand {
|
|
|
31
32
|
}
|
|
32
33
|
this.log(`Updating @xano/cli ${currentVersion} → ${latest}...`);
|
|
33
34
|
execSync(`npm install -g @xano/cli@${tag} --no-fund`, { stdio: 'inherit' });
|
|
35
|
+
clearUpdateCache();
|
|
34
36
|
this.log(`Updated to ${latest}`);
|
|
35
37
|
}
|
|
36
38
|
catch (error) {
|
|
@@ -13,6 +13,7 @@ export default class Push extends BaseCommand {
|
|
|
13
13
|
partial: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
records: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
15
|
'sync-guids': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
transaction: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
17
|
truncate: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
18
|
workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
19
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
@@ -86,6 +86,12 @@ Truncate all table records before importing
|
|
|
86
86
|
description: 'Write server-assigned GUIDs back to local files (use --no-sync-guids to skip)',
|
|
87
87
|
required: false,
|
|
88
88
|
}),
|
|
89
|
+
transaction: Flags.boolean({
|
|
90
|
+
allowNo: true,
|
|
91
|
+
default: true,
|
|
92
|
+
description: 'Wrap import in a database transaction (use --no-transaction for debugging purposes)',
|
|
93
|
+
required: false,
|
|
94
|
+
}),
|
|
89
95
|
truncate: Flags.boolean({
|
|
90
96
|
default: false,
|
|
91
97
|
description: 'Truncate all table records before importing',
|
|
@@ -179,6 +185,7 @@ Truncate all table records before importing
|
|
|
179
185
|
env: flags.env.toString(),
|
|
180
186
|
partial: flags.partial.toString(),
|
|
181
187
|
records: flags.records.toString(),
|
|
188
|
+
transaction: flags.transaction.toString(),
|
|
182
189
|
truncate: flags.truncate.toString(),
|
|
183
190
|
});
|
|
184
191
|
// POST the multidoc to the API
|
|
@@ -245,7 +252,27 @@ Truncate all table records before importing
|
|
|
245
252
|
this.renderPreview(preview, shouldDelete, workspaceId, flags.verbose);
|
|
246
253
|
// Check if there are any actual changes (exclude deletes when --delete is off)
|
|
247
254
|
const hasChanges = Object.values(preview.summary).some((c) => c.created > 0 || c.updated > 0 || (shouldDelete && c.deleted > 0) || c.truncated > 0);
|
|
248
|
-
if
|
|
255
|
+
// Detect if local files contain records that would be imported
|
|
256
|
+
const tablesWithRecords = flags.records
|
|
257
|
+
? documentEntries
|
|
258
|
+
.filter((d) => /^table\s+/m.test(d.content) && /\bitems\s*=\s*\[/m.test(d.content))
|
|
259
|
+
.map((d) => {
|
|
260
|
+
const nameMatch = d.content.match(/^table\s+(\S+)/m);
|
|
261
|
+
const itemCount = (d.content.match(/^\s*\{$/gm) || []).length;
|
|
262
|
+
return { name: nameMatch ? nameMatch[1] : 'unknown', records: itemCount };
|
|
263
|
+
})
|
|
264
|
+
: [];
|
|
265
|
+
const hasLocalRecords = tablesWithRecords.length > 0;
|
|
266
|
+
if (hasLocalRecords) {
|
|
267
|
+
this.log('');
|
|
268
|
+
this.log(ux.colorize('bold', '--- Records ---'));
|
|
269
|
+
this.log('');
|
|
270
|
+
for (const t of tablesWithRecords) {
|
|
271
|
+
this.log(` ${ux.colorize('yellow', 'UPSERT'.padEnd(16))} ${'table'.padEnd(18)} ${t.name} (${t.records} records)`);
|
|
272
|
+
}
|
|
273
|
+
this.log('');
|
|
274
|
+
}
|
|
275
|
+
if (!hasChanges && !hasLocalRecords) {
|
|
249
276
|
this.log('');
|
|
250
277
|
this.log('No changes to push.');
|
|
251
278
|
return;
|
package/dist/update-check.d.ts
CHANGED
package/dist/update-check.js
CHANGED
|
@@ -7,6 +7,18 @@ const CHECK_INTERVAL_MS = 8 * 60 * 60 * 1000; // 8 hours
|
|
|
7
7
|
function isBeta(version) {
|
|
8
8
|
return version.includes('beta') || version.includes('alpha') || version.includes('rc');
|
|
9
9
|
}
|
|
10
|
+
/** Returns true if `latest` is a higher semver than `current`. */
|
|
11
|
+
function isNewer(latest, current) {
|
|
12
|
+
const a = latest.split('.').map(Number);
|
|
13
|
+
const b = current.split('.').map(Number);
|
|
14
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
15
|
+
if ((a[i] ?? 0) > (b[i] ?? 0))
|
|
16
|
+
return true;
|
|
17
|
+
if ((a[i] ?? 0) < (b[i] ?? 0))
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
10
22
|
function readCache() {
|
|
11
23
|
try {
|
|
12
24
|
if (!fs.existsSync(UPDATE_CHECK_FILE))
|
|
@@ -21,6 +33,16 @@ function readCache() {
|
|
|
21
33
|
return null;
|
|
22
34
|
}
|
|
23
35
|
}
|
|
36
|
+
export function clearUpdateCache() {
|
|
37
|
+
try {
|
|
38
|
+
if (fs.existsSync(UPDATE_CHECK_FILE)) {
|
|
39
|
+
fs.unlinkSync(UPDATE_CHECK_FILE);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Silently fail
|
|
44
|
+
}
|
|
45
|
+
}
|
|
24
46
|
function writeCache(latestVersion) {
|
|
25
47
|
try {
|
|
26
48
|
const dir = path.dirname(UPDATE_CHECK_FILE);
|
|
@@ -62,7 +84,7 @@ export function checkForUpdate(currentVersion, forceCheck = false) {
|
|
|
62
84
|
writeCache(latestVersion);
|
|
63
85
|
}
|
|
64
86
|
}
|
|
65
|
-
if (!latestVersion || latestVersion
|
|
87
|
+
if (!latestVersion || !isNewer(latestVersion, currentVersion))
|
|
66
88
|
return null;
|
|
67
89
|
const yellow = '\u001B[33m';
|
|
68
90
|
const cyan = '\u001B[36m';
|