@statechange/xano-cli 0.2.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/README.md +251 -0
- package/dist/auth.d.ts +22 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +94 -0
- package/dist/auth.js.map +1 -0
- package/dist/commands/audit.d.ts +6 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +316 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/auth.d.ts +6 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +179 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/health.d.ts +6 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +115 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/history.d.ts +6 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +250 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/inventory.d.ts +6 -0
- package/dist/commands/inventory.d.ts.map +1 -0
- package/dist/commands/inventory.js +282 -0
- package/dist/commands/inventory.js.map +1 -0
- package/dist/commands/logs.d.ts +6 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +411 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/performance.d.ts +6 -0
- package/dist/commands/performance.d.ts.map +1 -0
- package/dist/commands/performance.js +520 -0
- package/dist/commands/performance.js.map +1 -0
- package/dist/commands/secure.d.ts +6 -0
- package/dist/commands/secure.d.ts.map +1 -0
- package/dist/commands/secure.js +52 -0
- package/dist/commands/secure.js.map +1 -0
- package/dist/commands/xanoscript.d.ts +6 -0
- package/dist/commands/xanoscript.d.ts.map +1 -0
- package/dist/commands/xanoscript.js +216 -0
- package/dist/commands/xanoscript.js.map +1 -0
- package/dist/commands/xray.d.ts +6 -0
- package/dist/commands/xray.d.ts.map +1 -0
- package/dist/commands/xray.js +194 -0
- package/dist/commands/xray.js.map +1 -0
- package/dist/format.d.ts +10 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +59 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/performance/load-analysis.d.ts +33 -0
- package/dist/performance/load-analysis.d.ts.map +1 -0
- package/dist/performance/load-analysis.js +290 -0
- package/dist/performance/load-analysis.js.map +1 -0
- package/dist/performance/stack-rollup.d.ts +57 -0
- package/dist/performance/stack-rollup.d.ts.map +1 -0
- package/dist/performance/stack-rollup.js +108 -0
- package/dist/performance/stack-rollup.js.map +1 -0
- package/dist/registry-client.d.ts +81 -0
- package/dist/registry-client.d.ts.map +1 -0
- package/dist/registry-client.js +333 -0
- package/dist/registry-client.js.map +1 -0
- package/dist/xano-client.d.ts +103 -0
- package/dist/xano-client.d.ts.map +1 -0
- package/dist/xano-client.js +399 -0
- package/dist/xano-client.js.map +1 -0
- package/package.json +49 -0
- package/skills/performance-analysis/SKILL.md +135 -0
- package/skills/xano-cli/SKILL.md +158 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Xano API Client - Portable version for CLI use
|
|
3
|
+
* Based on src/workers/xanoapi.ts
|
|
4
|
+
*/
|
|
5
|
+
const sinkCache = new Map();
|
|
6
|
+
const SINK_TTL_MS = 60_000; // 1 minute
|
|
7
|
+
/** Flush all sink caches (or a specific key) */
|
|
8
|
+
export function flushSinkCache(key) {
|
|
9
|
+
if (key) {
|
|
10
|
+
sinkCache.delete(key);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
sinkCache.clear();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class XanoClient {
|
|
17
|
+
instance;
|
|
18
|
+
token;
|
|
19
|
+
onTokenExpired;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.instance = config.instance;
|
|
22
|
+
this.token = config.token;
|
|
23
|
+
this.onTokenExpired = config.onTokenExpired;
|
|
24
|
+
}
|
|
25
|
+
/** Flush the sink cache (call after writes) */
|
|
26
|
+
flushCache() {
|
|
27
|
+
flushSinkCache();
|
|
28
|
+
}
|
|
29
|
+
getCached(key) {
|
|
30
|
+
const entry = sinkCache.get(key);
|
|
31
|
+
if (entry && Date.now() - entry.timestamp < SINK_TTL_MS) {
|
|
32
|
+
return entry.data;
|
|
33
|
+
}
|
|
34
|
+
if (entry)
|
|
35
|
+
sinkCache.delete(key);
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
setCache(key, data) {
|
|
39
|
+
sinkCache.set(key, { data, timestamp: Date.now() });
|
|
40
|
+
}
|
|
41
|
+
async fetch(path, options) {
|
|
42
|
+
const uri = `https://${this.instance}/${path}`;
|
|
43
|
+
const response = await fetch(uri, {
|
|
44
|
+
...(options || {}),
|
|
45
|
+
headers: {
|
|
46
|
+
...(options?.headers || {}),
|
|
47
|
+
Authorization: `Bearer ${this.token}`,
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
return response;
|
|
52
|
+
}
|
|
53
|
+
async fetchJson(path, options, attempts = 6, attemptTimeout = 10000) {
|
|
54
|
+
let currentAttempt = 0;
|
|
55
|
+
const opts = options ? { ...options } : {};
|
|
56
|
+
while (true) {
|
|
57
|
+
try {
|
|
58
|
+
const response = await this.fetch(path, opts);
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
if (currentAttempt >= attempts) {
|
|
61
|
+
throw new Error(`Failed to fetch ${path} after ${attempts} attempts: ${response.status} ${response.statusText}`);
|
|
62
|
+
}
|
|
63
|
+
else if (response.status >= 500) {
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, attemptTimeout * (currentAttempt + 1)));
|
|
65
|
+
currentAttempt++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
else if (response.status === 401 && this.onTokenExpired && currentAttempt === 0) {
|
|
69
|
+
// Token rejected — try to refresh via callback
|
|
70
|
+
try {
|
|
71
|
+
this.token = await this.onTokenExpired();
|
|
72
|
+
currentAttempt++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Refresh failed — fall through to throw the API error
|
|
77
|
+
}
|
|
78
|
+
const errorText = await response.text();
|
|
79
|
+
const apiError = new Error(`Xano API error: 401 Unauthorized - ${errorText}\n\nYour Xano session may have expired. Run 'sc-xano auth status' to check token health.`);
|
|
80
|
+
apiError.isApiError = true;
|
|
81
|
+
throw apiError;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const errorText = await response.text();
|
|
85
|
+
let hint = "";
|
|
86
|
+
if (response.status === 401 || response.status === 403) {
|
|
87
|
+
hint = `\n\nRun 'sc-xano auth status' to check your Xano session.`;
|
|
88
|
+
}
|
|
89
|
+
const apiError = new Error(`Xano API error: ${response.status} ${response.statusText} - ${errorText}${hint}`);
|
|
90
|
+
apiError.isApiError = true;
|
|
91
|
+
throw apiError;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const json = (await response.json());
|
|
95
|
+
return json;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
// Don't retry on 4xx API errors — only retry on network/timeout failures
|
|
99
|
+
if (error.isApiError || currentAttempt >= attempts) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
await new Promise((resolve) => setTimeout(resolve, attemptTimeout * (currentAttempt + 1)));
|
|
103
|
+
currentAttempt++;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Workspace methods
|
|
108
|
+
async getWorkspaces() {
|
|
109
|
+
return this.fetchJson(`api:mvp-admin/workspace`);
|
|
110
|
+
}
|
|
111
|
+
// Function methods (cached via sink)
|
|
112
|
+
async getFunctions(workspaceId, branchId = 0) {
|
|
113
|
+
const cacheKey = `functions:${workspaceId}:${branchId}`;
|
|
114
|
+
const cached = this.getCached(cacheKey);
|
|
115
|
+
if (cached)
|
|
116
|
+
return cached;
|
|
117
|
+
const result = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/functions?branch_id=${branchId}`);
|
|
118
|
+
this.setCache(cacheKey, result);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
/** Get a single function by plucking from the sink list */
|
|
122
|
+
async getFunction(functionId, workspaceId, branchId = 0) {
|
|
123
|
+
if (workspaceId != null) {
|
|
124
|
+
const { functions } = await this.getFunctions(workspaceId, branchId);
|
|
125
|
+
const func = functions.find((f) => f.id === functionId);
|
|
126
|
+
if (func)
|
|
127
|
+
return func;
|
|
128
|
+
}
|
|
129
|
+
// Fallback to individual endpoint (may 404 on some instances)
|
|
130
|
+
return this.fetchJson(`api:mvp-admin/function/${functionId}`);
|
|
131
|
+
}
|
|
132
|
+
// App/API methods (cached via sink)
|
|
133
|
+
async getAPIAppsAndQueries(workspaceId, branchId = 0) {
|
|
134
|
+
const cacheKey = `api:${workspaceId}:${branchId}`;
|
|
135
|
+
const cached = this.getCached(cacheKey);
|
|
136
|
+
if (cached)
|
|
137
|
+
return cached;
|
|
138
|
+
const result = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/api?branch_id=${branchId}`);
|
|
139
|
+
this.setCache(cacheKey, result);
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
async getApp(appId, branchId) {
|
|
143
|
+
return this.fetchJson(`api:mvp-admin/app/${appId}?branch_id=${branchId}`);
|
|
144
|
+
}
|
|
145
|
+
async updateApp(app) {
|
|
146
|
+
this.flushCache();
|
|
147
|
+
return this.fetchJson(`api:mvp-admin/app/${app.id}`, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
data: app,
|
|
151
|
+
last_updated_at: app.updated_at,
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Query (endpoint) methods
|
|
156
|
+
async getQuery(queryId) {
|
|
157
|
+
return this.fetchJson(`api:mvp-admin/query/${queryId}`);
|
|
158
|
+
}
|
|
159
|
+
async updateQuery(query) {
|
|
160
|
+
this.flushCache();
|
|
161
|
+
return this.fetchJson(`api:mvp-admin/query/${query.id}`, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
body: JSON.stringify({
|
|
164
|
+
data: query,
|
|
165
|
+
last_updated_at: query.updated_at,
|
|
166
|
+
}),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Task update
|
|
170
|
+
async updateTask(task) {
|
|
171
|
+
this.flushCache();
|
|
172
|
+
return this.fetchJson(`api:mvp-admin/task/${task.id}`, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
body: JSON.stringify({
|
|
175
|
+
data: task,
|
|
176
|
+
last_updated_at: task.updated_at,
|
|
177
|
+
}),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// Trigger update
|
|
181
|
+
async updateTrigger(trigger) {
|
|
182
|
+
this.flushCache();
|
|
183
|
+
return this.fetchJson(`api:mvp-admin/trigger/${trigger.id}`, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
body: JSON.stringify({
|
|
186
|
+
data: trigger,
|
|
187
|
+
last_updated_at: trigger.updated_at,
|
|
188
|
+
}),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// History methods
|
|
192
|
+
async getRequestHistory(workspaceId, page = 1, branchId = -1) {
|
|
193
|
+
return this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/request?page=${page}&branch_id=${branchId}`);
|
|
194
|
+
}
|
|
195
|
+
async getRequestHistoryForQuery(queryId, page = 1, branchId = -1) {
|
|
196
|
+
return this.fetchJson(`api:mvp-admin/query/${queryId}/request?page=${page}&branch_id=${branchId}`);
|
|
197
|
+
}
|
|
198
|
+
async getRequest(requestId) {
|
|
199
|
+
return this.fetchJson(`api:mvp-admin/request/${requestId}`);
|
|
200
|
+
}
|
|
201
|
+
// Task methods (cached via sink)
|
|
202
|
+
async getTasks(workspaceId, branchId = 0) {
|
|
203
|
+
const cacheKey = `tasks:${workspaceId}:${branchId}`;
|
|
204
|
+
const cached = this.getCached(cacheKey);
|
|
205
|
+
if (cached)
|
|
206
|
+
return cached;
|
|
207
|
+
const payload = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/tasks?branch_id=${branchId}`);
|
|
208
|
+
const tasks = payload.tasks ?? [];
|
|
209
|
+
this.setCache(cacheKey, tasks);
|
|
210
|
+
return tasks;
|
|
211
|
+
}
|
|
212
|
+
async getTaskHistory(taskId, page = 1) {
|
|
213
|
+
return this.fetchJson(`api:mvp-admin/task/${taskId}/history?page=${page}`);
|
|
214
|
+
}
|
|
215
|
+
// Trigger methods (cached via sink)
|
|
216
|
+
async getTriggers(workspaceId, branchId = 0) {
|
|
217
|
+
const cacheKey = `triggers:${workspaceId}:${branchId}`;
|
|
218
|
+
const cached = this.getCached(cacheKey);
|
|
219
|
+
if (cached)
|
|
220
|
+
return cached;
|
|
221
|
+
const payload = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/trigger?branch_id=${branchId}`);
|
|
222
|
+
const triggers = payload.triggers ?? [];
|
|
223
|
+
this.setCache(cacheKey, triggers);
|
|
224
|
+
return triggers;
|
|
225
|
+
}
|
|
226
|
+
async getTriggerHistory(triggerId, branchId = 0, page = 1) {
|
|
227
|
+
return this.fetchJson(`api:mvp-admin/trigger/${triggerId}/request?branch_id=${branchId}&page=${page}`);
|
|
228
|
+
}
|
|
229
|
+
// MCP/Tool methods (cached via sink)
|
|
230
|
+
async getMCPServers(workspaceId, branchId = 0) {
|
|
231
|
+
const cacheKey = `toolsets:${workspaceId}:${branchId}`;
|
|
232
|
+
const cached = this.getCached(cacheKey);
|
|
233
|
+
if (cached)
|
|
234
|
+
return cached;
|
|
235
|
+
const payload = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/toolset?branch_id=${branchId}`);
|
|
236
|
+
const toolsets = payload.toolsets ?? [];
|
|
237
|
+
this.setCache(cacheKey, toolsets);
|
|
238
|
+
return toolsets;
|
|
239
|
+
}
|
|
240
|
+
async getMCPServerHistory(toolId, branchId = 0, page = 1) {
|
|
241
|
+
return this.fetchJson(`api:mvp-admin/toolset/${toolId}/request?branch_id=${branchId}&page=${page}`);
|
|
242
|
+
}
|
|
243
|
+
// Middleware methods (cached via sink)
|
|
244
|
+
async getMiddleware(workspaceId, branchId = 0) {
|
|
245
|
+
const cacheKey = `middleware:${workspaceId}:${branchId}`;
|
|
246
|
+
const cached = this.getCached(cacheKey);
|
|
247
|
+
if (cached)
|
|
248
|
+
return cached;
|
|
249
|
+
const payload = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/middleware?branch_id=${branchId}`);
|
|
250
|
+
const middleware = payload.middleware ?? [];
|
|
251
|
+
this.setCache(cacheKey, middleware);
|
|
252
|
+
return middleware;
|
|
253
|
+
}
|
|
254
|
+
// Addon methods (cached via sink)
|
|
255
|
+
async getAddons(workspaceId, branchId = 0) {
|
|
256
|
+
const cacheKey = `addons:${workspaceId}:${branchId}`;
|
|
257
|
+
const cached = this.getCached(cacheKey);
|
|
258
|
+
if (cached)
|
|
259
|
+
return cached;
|
|
260
|
+
const payload = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink/addons?branch_id=${branchId}`);
|
|
261
|
+
const addons = payload.addons ?? [];
|
|
262
|
+
this.setCache(cacheKey, addons);
|
|
263
|
+
return addons;
|
|
264
|
+
}
|
|
265
|
+
// Workspace sink — tables/dbos (cached)
|
|
266
|
+
async getWorkspaceSink(workspaceId) {
|
|
267
|
+
const cacheKey = `sink:${workspaceId}`;
|
|
268
|
+
const cached = this.getCached(cacheKey);
|
|
269
|
+
if (cached)
|
|
270
|
+
return cached;
|
|
271
|
+
const result = await this.fetchJson(`api:mvp-admin/workspace/${workspaceId}/sink`);
|
|
272
|
+
this.setCache(cacheKey, result);
|
|
273
|
+
return result;
|
|
274
|
+
}
|
|
275
|
+
/** Get a single table by plucking from the workspace sink */
|
|
276
|
+
async getTable(tableId, workspaceId) {
|
|
277
|
+
if (workspaceId != null) {
|
|
278
|
+
const sink = await this.getWorkspaceSink(workspaceId);
|
|
279
|
+
const table = (sink.dbos ?? []).find((t) => t.id === tableId);
|
|
280
|
+
if (table)
|
|
281
|
+
return table;
|
|
282
|
+
}
|
|
283
|
+
// Fallback to individual endpoint
|
|
284
|
+
return this.fetchJson(`api:mvp-admin/dbo/${tableId}`);
|
|
285
|
+
}
|
|
286
|
+
// Task history item detail
|
|
287
|
+
async getTaskHistoryItem(taskId, runId) {
|
|
288
|
+
return this.fetchJson(`api:mvp-admin/task/${taskId}/history/${runId}`);
|
|
289
|
+
}
|
|
290
|
+
// XanoScript generation with 429 rate-limit retry
|
|
291
|
+
async generateXanoScript(workspaceId, data, kind) {
|
|
292
|
+
const body = JSON.stringify({ data, kind, path: "", type: "xs" });
|
|
293
|
+
const maxRetries = 5;
|
|
294
|
+
const baseDelay = 1000;
|
|
295
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
296
|
+
const response = await this.fetch(`api:mvp-admin/workspace/${workspaceId}/script`, { method: "POST", body });
|
|
297
|
+
if (response.ok) {
|
|
298
|
+
const result = await response.json();
|
|
299
|
+
return { status: "success", payload: result };
|
|
300
|
+
}
|
|
301
|
+
if (response.status === 429 && attempt < maxRetries) {
|
|
302
|
+
const delay = baseDelay * Math.pow(2, attempt);
|
|
303
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const result = await response.json();
|
|
308
|
+
return { status: "error", payload: result };
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return {
|
|
312
|
+
status: "error",
|
|
313
|
+
payload: {
|
|
314
|
+
message: response.status === 429
|
|
315
|
+
? `Rate limited. Failed after ${maxRetries} retries.`
|
|
316
|
+
: "Failed to generate XanoScript",
|
|
317
|
+
doIgnore: response.status !== 429,
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return { status: "error", payload: { message: "Failed to generate XanoScript", doIgnore: true } };
|
|
323
|
+
}
|
|
324
|
+
// XanoScript conversion with 429 rate-limit retry
|
|
325
|
+
async convertXanoScript(workspaceId, script) {
|
|
326
|
+
const body = JSON.stringify({ script, type: "xs" });
|
|
327
|
+
const maxRetries = 5;
|
|
328
|
+
const baseDelay = 1000;
|
|
329
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
330
|
+
const response = await this.fetch(`api:mvp-admin/workspace/${workspaceId}/script/convert`, { method: "POST", body });
|
|
331
|
+
if (response.ok) {
|
|
332
|
+
const result = await response.json();
|
|
333
|
+
return { status: "success", payload: result };
|
|
334
|
+
}
|
|
335
|
+
if (response.status === 429 && attempt < maxRetries) {
|
|
336
|
+
const delay = baseDelay * Math.pow(2, attempt);
|
|
337
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
const result = await response.json();
|
|
342
|
+
return { status: "error", payload: result };
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
return {
|
|
346
|
+
status: "error",
|
|
347
|
+
payload: {
|
|
348
|
+
message: response.status === 429
|
|
349
|
+
? `Rate limited. Failed after ${maxRetries} retries.`
|
|
350
|
+
: "Failed to convert XanoScript",
|
|
351
|
+
doIgnore: response.status !== 429,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return { status: "error", payload: { message: "Failed to convert XanoScript", doIgnore: true } };
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
export class XanoMasterClient {
|
|
360
|
+
token;
|
|
361
|
+
constructor(config) {
|
|
362
|
+
this.token = config.token;
|
|
363
|
+
}
|
|
364
|
+
async fetchJson(path, options) {
|
|
365
|
+
const url = `https://app.xano.com/api:master/${path}`;
|
|
366
|
+
const response = await fetch(url, {
|
|
367
|
+
...(options || {}),
|
|
368
|
+
headers: {
|
|
369
|
+
...(options?.headers || {}),
|
|
370
|
+
Authorization: `Bearer ${this.token}`,
|
|
371
|
+
"Content-Type": "application/json",
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
if (!response.ok) {
|
|
375
|
+
const errorText = await response.text();
|
|
376
|
+
throw new Error(`Xano Master API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
377
|
+
}
|
|
378
|
+
return (await response.json());
|
|
379
|
+
}
|
|
380
|
+
async getInstances() {
|
|
381
|
+
return this.fetchJson("instance");
|
|
382
|
+
}
|
|
383
|
+
async getInstanceDatabases(instanceId) {
|
|
384
|
+
return this.fetchJson(`instance/${instanceId}/request-history/database`);
|
|
385
|
+
}
|
|
386
|
+
async clearInstanceDatabases(instanceId, tables, force = false) {
|
|
387
|
+
await this.fetchJson(`instance/${instanceId}/request-history/database/clear`, {
|
|
388
|
+
method: "POST",
|
|
389
|
+
body: JSON.stringify({ tables, force }),
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async restartDeployment(instanceId, name) {
|
|
393
|
+
await this.fetchJson(`instance/${instanceId}/deployments/restart`, {
|
|
394
|
+
method: "POST",
|
|
395
|
+
body: JSON.stringify({ name }),
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=xano-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xano-client.js","sourceRoot":"","sources":["../src/xano-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@statechange/xano-cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "CLI for Xano workspace management, performance analysis, XanoScript generation, and operational insights via private APIs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sc-xano": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"skills",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"xano",
|
|
23
|
+
"cli",
|
|
24
|
+
"statechange",
|
|
25
|
+
"xanoscript",
|
|
26
|
+
"performance",
|
|
27
|
+
"audit",
|
|
28
|
+
"no-code",
|
|
29
|
+
"backend"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/statechange/xano-cli.git"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/statechange/xano-cli#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/statechange/xano-cli/issues"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@statechange/xano-xray": "^0.1.0",
|
|
42
|
+
"commander": "^11.1.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.10.0",
|
|
46
|
+
"tsx": "^4.21.0",
|
|
47
|
+
"typescript": "^5.3.0"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-analysis
|
|
3
|
+
description: Analyze and optimize Xano workspace performance. Use when the user wants to find slow endpoints, trace execution bottlenecks, deep-dive request stacks, or understand why their Xano API is slow. Also use when the user mentions "performance," "slow endpoint," "bottleneck," "stack trace," or "optimization."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Xano Performance Analysis
|
|
7
|
+
|
|
8
|
+
Requires the `sc-xano` CLI to be authenticated (see the `sc-xano` skill).
|
|
9
|
+
|
|
10
|
+
## Workflow: "Why is my workspace slow?"
|
|
11
|
+
|
|
12
|
+
Start broad, then drill into specifics.
|
|
13
|
+
|
|
14
|
+
### Step 1: Identify the hottest endpoints
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @statechange/xano-cli performance top-endpoints --lookback 24 --format yaml
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Returns all endpoints, tasks, triggers, and MCP tools ranked by total duration. Look at:
|
|
21
|
+
- **Total duration** — which objects consume the most aggregate server time
|
|
22
|
+
- **Avg duration** — which individual calls are slowest
|
|
23
|
+
- **Request count** — high-frequency low-duration items may still matter
|
|
24
|
+
|
|
25
|
+
### Step 2: Trace the worst offender
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @statechange/xano-cli performance trace endpoint <query-id> --samples 10 --format yaml
|
|
29
|
+
npx @statechange/xano-cli performance trace task <task-id> --samples 10 --format yaml
|
|
30
|
+
npx @statechange/xano-cli performance trace trigger <trigger-id> --samples 10 --format yaml
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Note:** Task history items don't include stack traces (Xano API limitation). Trace will show duration percentiles but no step breakdown for tasks.
|
|
34
|
+
|
|
35
|
+
The trace output shows:
|
|
36
|
+
- **Duration percentiles** (avg, p50, p95, p99) across samples
|
|
37
|
+
- **Step breakdown** aggregated by `_xsid` — which steps consume the most time across all executions
|
|
38
|
+
- **Functions called** — which custom functions are invoked and how often
|
|
39
|
+
- Steps with high `occurrences` relative to `samples` indicate they run inside loops
|
|
40
|
+
|
|
41
|
+
### Step 3: Deep-dive a single request
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @statechange/xano-cli performance deep-dive <request-id> --format yaml
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This shows:
|
|
48
|
+
- **Recursive stack tree** with direct vs rollup timing at each step
|
|
49
|
+
- **pct_of_total** / **pct_of_parent** — percentage breakdowns
|
|
50
|
+
- **iterations** — how many times loop bodies executed
|
|
51
|
+
- **Warnings** for slow steps inside loops (DB queries, lambdas, external API calls)
|
|
52
|
+
- **functions_called** summary with call counts and total time
|
|
53
|
+
- **stack_truncated: true** means Xano capped the stack — see "Handling truncated stacks" below
|
|
54
|
+
|
|
55
|
+
### Step 4: X-Ray the hot function
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx @statechange/xano-cli xray function --id <function-id> --format yaml
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Static analysis of the function's step hierarchy — warnings about nested slow steps, dependencies on other functions.
|
|
62
|
+
|
|
63
|
+
### Step 5: Read the source
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx @statechange/xano-cli xanoscript generate function <function-id>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Generate XanoScript source to understand what the function does and recommend fixes.
|
|
70
|
+
|
|
71
|
+
## Workflow: "Why do I get errors?"
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# 1. Find requests with error status codes
|
|
75
|
+
npx @statechange/xano-cli history requests --format yaml
|
|
76
|
+
|
|
77
|
+
# 2. Deep-dive the error request to see which step failed
|
|
78
|
+
npx @statechange/xano-cli performance deep-dive <error-request-id> --format yaml
|
|
79
|
+
|
|
80
|
+
# 3. X-Ray the failing function for structural issues
|
|
81
|
+
npx @statechange/xano-cli xray function --id <failing-function-id> --format yaml
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Workflow: "Which functions should I optimize first?"
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# 1. Get endpoint ranking
|
|
88
|
+
npx @statechange/xano-cli performance top-endpoints --lookback 24 --format yaml
|
|
89
|
+
|
|
90
|
+
# 2. Trace the top 3-5 endpoints
|
|
91
|
+
npx @statechange/xano-cli performance trace endpoint <id1> --format yaml
|
|
92
|
+
npx @statechange/xano-cli performance trace endpoint <id2> --format yaml
|
|
93
|
+
npx @statechange/xano-cli performance trace endpoint <id3> --format yaml
|
|
94
|
+
|
|
95
|
+
# 3. Look at functions_called across all traces
|
|
96
|
+
# Rank by: avg_seconds_per_call x total_calls x number_of_callers
|
|
97
|
+
# This gives "optimization ROI" — fixing one function improves many endpoints
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Handling truncated stacks
|
|
101
|
+
|
|
102
|
+
When `stack_truncated: true` appears in a deep-dive, Xano capped the stack at the endpoint's retention limit. Large `direct_seconds` on a function step with truncation means the real bottleneck is hidden.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 1. Check current retention settings
|
|
106
|
+
npx @statechange/xano-cli logs show endpoint <id>
|
|
107
|
+
|
|
108
|
+
# 2. Set to unlimited to capture full stacks
|
|
109
|
+
npx @statechange/xano-cli logs set endpoint <id> --limit -1
|
|
110
|
+
|
|
111
|
+
# 3. Watch for new executions
|
|
112
|
+
npx @statechange/xano-cli logs watch endpoint <id>
|
|
113
|
+
|
|
114
|
+
# 4. Deep-dive the new (untruncated) execution
|
|
115
|
+
npx @statechange/xano-cli performance deep-dive <new-request-id> --format yaml
|
|
116
|
+
|
|
117
|
+
# 5. Restore the default limit when done
|
|
118
|
+
npx @statechange/xano-cli logs set endpoint <id> --limit 100
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Interpreting Results
|
|
122
|
+
|
|
123
|
+
- **High `direct_seconds` with no children** — the step itself is slow (external API call, lambda, complex query)
|
|
124
|
+
- **Low `direct_seconds` but high `rollup_seconds`** — children are slow, drill deeper
|
|
125
|
+
- **Same `_xsid` with high `occurrences`** in trace — step runs inside a loop. Multiply `avg_rollup_seconds` by occurrences/samples to get per-request impact
|
|
126
|
+
- **DB queries inside loops** (warnings) — classic N+1 problem. Move the query outside the loop or use a batch query
|
|
127
|
+
- **Lambda steps with high timing** — interpreted code blocks are slower than native Xano steps
|
|
128
|
+
|
|
129
|
+
### History retention values
|
|
130
|
+
|
|
131
|
+
- `limit: 100` (default) — keeps top 100 stack steps, may truncate deep stacks
|
|
132
|
+
- `limit: -1` — unlimited, captures full stack (use for debugging)
|
|
133
|
+
- `limit: 0` — disabled, no history retained
|
|
134
|
+
- `inherit: true` — inherits from the parent API app settings
|
|
135
|
+
- `enabled: false` — history recording is off entirely
|