@xano/cli 0.0.37 → 0.0.39

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 (114) hide show
  1. package/README.md +325 -102
  2. package/dist/commands/auth/index.d.ts +0 -2
  3. package/dist/commands/auth/index.js +2 -55
  4. package/dist/commands/profile/create/index.d.ts +0 -2
  5. package/dist/commands/profile/create/index.js +0 -15
  6. package/dist/commands/profile/edit/index.d.ts +0 -4
  7. package/dist/commands/profile/edit/index.js +7 -38
  8. package/dist/commands/profile/wizard/index.d.ts +0 -2
  9. package/dist/commands/profile/wizard/index.js +0 -106
  10. package/dist/commands/profile/{project → workspace}/index.d.ts +1 -1
  11. package/dist/commands/profile/{project → workspace}/index.js +10 -10
  12. package/dist/commands/release/delete/index.d.ts +2 -4
  13. package/dist/commands/release/delete/index.js +39 -12
  14. package/dist/commands/release/edit/index.d.ts +2 -4
  15. package/dist/commands/release/edit/index.js +31 -5
  16. package/dist/commands/release/export/index.d.ts +2 -4
  17. package/dist/commands/release/export/index.js +39 -11
  18. package/dist/commands/release/get/index.d.ts +2 -4
  19. package/dist/commands/release/get/index.js +31 -5
  20. package/dist/commands/release/pull/index.d.ts +31 -0
  21. package/dist/commands/release/pull/index.js +345 -0
  22. package/dist/commands/release/push/index.d.ts +26 -0
  23. package/dist/commands/release/push/index.js +230 -0
  24. package/dist/commands/tenant/backup/delete/index.d.ts +1 -1
  25. package/dist/commands/tenant/backup/delete/index.js +8 -9
  26. package/dist/commands/tenant/backup/export/index.d.ts +1 -1
  27. package/dist/commands/tenant/backup/export/index.js +9 -10
  28. package/dist/commands/tenant/backup/restore/index.d.ts +1 -1
  29. package/dist/commands/tenant/backup/restore/index.js +8 -9
  30. package/dist/commands/tenant/cluster/create/index.d.ts +18 -0
  31. package/dist/commands/tenant/cluster/create/index.js +149 -0
  32. package/dist/commands/{run/sessions/start → tenant/cluster/delete}/index.d.ts +9 -3
  33. package/dist/commands/tenant/cluster/delete/index.js +125 -0
  34. package/dist/commands/tenant/cluster/edit/index.d.ts +22 -0
  35. package/dist/commands/tenant/cluster/edit/index.js +128 -0
  36. package/dist/commands/{run/sessions → tenant/cluster}/get/index.d.ts +7 -3
  37. package/dist/commands/tenant/cluster/get/index.js +114 -0
  38. package/dist/commands/{run/info → tenant/cluster/license/get}/index.d.ts +10 -7
  39. package/dist/commands/tenant/cluster/license/get/index.js +118 -0
  40. package/dist/commands/tenant/cluster/license/set/index.d.ts +21 -0
  41. package/dist/commands/tenant/cluster/license/set/index.js +132 -0
  42. package/dist/commands/{run/env → tenant/cluster}/list/index.d.ts +3 -3
  43. package/dist/commands/tenant/cluster/list/index.js +109 -0
  44. package/dist/commands/tenant/create/index.d.ts +6 -3
  45. package/dist/commands/tenant/create/index.js +28 -20
  46. package/dist/commands/tenant/deploy_platform/index.d.ts +1 -1
  47. package/dist/commands/tenant/deploy_platform/index.js +8 -9
  48. package/dist/commands/tenant/deploy_release/index.d.ts +1 -1
  49. package/dist/commands/tenant/deploy_release/index.js +8 -9
  50. package/dist/commands/tenant/env/delete/index.d.ts +19 -0
  51. package/dist/commands/tenant/env/delete/index.js +139 -0
  52. package/dist/commands/{run/projects/create → tenant/env/get}/index.d.ts +7 -4
  53. package/dist/commands/tenant/env/get/index.js +113 -0
  54. package/dist/commands/{run/projects/update → tenant/env/get_all}/index.d.ts +7 -5
  55. package/dist/commands/tenant/env/get_all/index.js +123 -0
  56. package/dist/commands/{run/secrets/get → tenant/env/list}/index.d.ts +5 -3
  57. package/dist/commands/tenant/env/list/index.js +116 -0
  58. package/dist/commands/tenant/env/set/index.d.ts +18 -0
  59. package/dist/commands/tenant/env/set/index.js +122 -0
  60. package/dist/commands/tenant/env/set_all/index.d.ts +18 -0
  61. package/dist/commands/tenant/env/set_all/index.js +131 -0
  62. package/dist/commands/tenant/get/index.js +6 -5
  63. package/dist/commands/tenant/impersonate/index.d.ts +19 -0
  64. package/dist/commands/tenant/impersonate/index.js +146 -0
  65. package/dist/commands/tenant/license/get/index.d.ts +18 -0
  66. package/dist/commands/tenant/license/get/index.js +127 -0
  67. package/dist/commands/tenant/license/set/index.d.ts +19 -0
  68. package/dist/commands/tenant/license/set/index.js +141 -0
  69. package/dist/commands/tenant/list/index.js +6 -6
  70. package/dist/commands/tenant/pull/index.d.ts +31 -0
  71. package/dist/commands/tenant/pull/index.js +327 -0
  72. package/dist/commands/tenant/push/index.d.ts +24 -0
  73. package/dist/commands/tenant/push/index.js +245 -0
  74. package/oclif.manifest.json +2218 -1813
  75. package/package.json +1 -19
  76. package/dist/commands/run/env/delete/index.d.ts +0 -14
  77. package/dist/commands/run/env/delete/index.js +0 -65
  78. package/dist/commands/run/env/get/index.d.ts +0 -14
  79. package/dist/commands/run/env/get/index.js +0 -52
  80. package/dist/commands/run/env/list/index.js +0 -56
  81. package/dist/commands/run/env/set/index.d.ts +0 -14
  82. package/dist/commands/run/env/set/index.js +0 -51
  83. package/dist/commands/run/exec/index.d.ts +0 -31
  84. package/dist/commands/run/exec/index.js +0 -431
  85. package/dist/commands/run/info/index.js +0 -160
  86. package/dist/commands/run/projects/create/index.js +0 -75
  87. package/dist/commands/run/projects/delete/index.d.ts +0 -14
  88. package/dist/commands/run/projects/delete/index.js +0 -65
  89. package/dist/commands/run/projects/list/index.d.ts +0 -13
  90. package/dist/commands/run/projects/list/index.js +0 -66
  91. package/dist/commands/run/projects/update/index.js +0 -86
  92. package/dist/commands/run/secrets/delete/index.d.ts +0 -14
  93. package/dist/commands/run/secrets/delete/index.js +0 -65
  94. package/dist/commands/run/secrets/get/index.js +0 -52
  95. package/dist/commands/run/secrets/list/index.d.ts +0 -12
  96. package/dist/commands/run/secrets/list/index.js +0 -60
  97. package/dist/commands/run/secrets/set/index.d.ts +0 -16
  98. package/dist/commands/run/secrets/set/index.js +0 -74
  99. package/dist/commands/run/sessions/delete/index.d.ts +0 -14
  100. package/dist/commands/run/sessions/delete/index.js +0 -65
  101. package/dist/commands/run/sessions/get/index.js +0 -72
  102. package/dist/commands/run/sessions/list/index.d.ts +0 -13
  103. package/dist/commands/run/sessions/list/index.js +0 -64
  104. package/dist/commands/run/sessions/start/index.js +0 -56
  105. package/dist/commands/run/sessions/stop/index.d.ts +0 -14
  106. package/dist/commands/run/sessions/stop/index.js +0 -56
  107. package/dist/commands/run/sink/get/index.d.ts +0 -14
  108. package/dist/commands/run/sink/get/index.js +0 -63
  109. package/dist/lib/base-run-command.d.ts +0 -41
  110. package/dist/lib/base-run-command.js +0 -75
  111. package/dist/lib/run-http-client.d.ts +0 -64
  112. package/dist/lib/run-http-client.js +0 -171
  113. package/dist/lib/run-types.d.ts +0 -226
  114. package/dist/lib/run-types.js +0 -5
@@ -1,431 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import { execSync } from 'node:child_process';
3
- import * as fs from 'node:fs';
4
- import * as os from 'node:os';
5
- import * as path from 'node:path';
6
- import BaseRunCommand from '../../../lib/base-run-command.js';
7
- export default class RunExec extends BaseRunCommand {
8
- static args = {
9
- path: Args.string({
10
- description: 'Path to file or directory containing XanoScript code (directory creates multidoc from .xs files)',
11
- required: false,
12
- }),
13
- };
14
- static description = 'Execute XanoScript code (job or service)';
15
- static examples = [
16
- `$ xano run exec script.xs
17
- Executed successfully!
18
- ...
19
- `,
20
- `$ xano run exec ./my-workspace
21
- # Executes all .xs files in directory as multidoc
22
- Executed successfully!
23
- ...
24
- `,
25
- `$ xano run exec script.xs --edit
26
- # Opens script.xs in $EDITOR, then executes
27
- Executed successfully!
28
- ...
29
- `,
30
- `$ cat script.xs | xano run exec --stdin
31
- Executed successfully!
32
- ...
33
- `,
34
- `$ xano run exec script.xs -o json
35
- {
36
- "run": { ... }
37
- }
38
- `,
39
- `$ xano run exec script.xs -a args.json
40
- # Executes with input arguments from args.json
41
- Executed successfully!
42
- ...
43
- `,
44
- `$ xano run exec script.xs --env API_KEY=secret --env DEBUG=true
45
- # Executes with environment variable overrides
46
- Executed successfully!
47
- ...
48
- `,
49
- ];
50
- static flags = {
51
- ...BaseRunCommand.baseFlags,
52
- args: Flags.string({
53
- char: 'a',
54
- description: 'Path or URL to JSON file containing input arguments',
55
- required: false,
56
- }),
57
- edit: Flags.boolean({
58
- char: 'e',
59
- default: false,
60
- description: 'Open file in editor before running (requires path argument or --file)',
61
- required: false,
62
- }),
63
- env: Flags.string({
64
- description: 'Environment variable override (key=value)',
65
- multiple: true,
66
- required: false,
67
- }),
68
- file: Flags.string({
69
- char: 'f',
70
- description: 'Path or URL to file containing XanoScript code (deprecated: use path argument instead)',
71
- exclusive: ['stdin'],
72
- required: false,
73
- }),
74
- output: Flags.string({
75
- char: 'o',
76
- default: 'summary',
77
- description: 'Output format',
78
- options: ['summary', 'json'],
79
- required: false,
80
- }),
81
- stdin: Flags.boolean({
82
- char: 's',
83
- default: false,
84
- description: 'Read XanoScript code from stdin',
85
- exclusive: ['file'],
86
- required: false,
87
- }),
88
- };
89
- async run() {
90
- const { args, flags } = await this.parse(RunExec);
91
- // Initialize with project required
92
- await this.initRunCommandWithProject(flags.profile, flags.verbose);
93
- // Determine input source: path argument, --file flag, or --stdin
94
- const inputPath = args.path || flags.file;
95
- // Validate --edit flag requirements
96
- if (flags.edit) {
97
- if (!inputPath) {
98
- this.error('--edit requires a file path (either path argument or --file flag)');
99
- }
100
- if (this.isUrl(inputPath)) {
101
- this.error('--edit cannot be used with URLs');
102
- }
103
- if (fs.existsSync(inputPath) && fs.statSync(inputPath).isDirectory()) {
104
- this.error('--edit cannot be used with directories');
105
- }
106
- }
107
- // Read XanoScript content
108
- let xanoscript;
109
- if (inputPath) {
110
- if (this.isUrl(inputPath)) {
111
- // Fetch URL content
112
- try {
113
- const response = await fetch(inputPath);
114
- if (!response.ok) {
115
- this.error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
116
- }
117
- xanoscript = await response.text();
118
- }
119
- catch (error) {
120
- this.error(`Failed to fetch URL '${inputPath}': ${error}`);
121
- }
122
- }
123
- else if (fs.existsSync(inputPath) && fs.statSync(inputPath).isDirectory()) {
124
- // Handle directory - collect .xs files and create multidoc
125
- xanoscript = this.loadMultidocFromDirectory(inputPath);
126
- }
127
- else if (flags.edit) {
128
- // If edit flag is set, copy to temp file and open in editor
129
- const fileToRead = await this.editFile(inputPath);
130
- xanoscript = fs.readFileSync(fileToRead, 'utf8');
131
- // Clean up temp file
132
- try {
133
- fs.unlinkSync(fileToRead);
134
- }
135
- catch {
136
- // Ignore cleanup errors
137
- }
138
- }
139
- else {
140
- try {
141
- xanoscript = fs.readFileSync(inputPath, 'utf8');
142
- }
143
- catch (error) {
144
- this.error(`Failed to read file '${inputPath}': ${error}`);
145
- }
146
- }
147
- }
148
- else if (flags.stdin) {
149
- try {
150
- xanoscript = await this.readStdin();
151
- }
152
- catch (error) {
153
- this.error(`Failed to read from stdin: ${error}`);
154
- }
155
- }
156
- else {
157
- this.error('Either a path argument, --file, or --stdin must be specified to provide XanoScript code');
158
- }
159
- // Validate xanoscript is not empty
160
- if (!xanoscript || xanoscript.trim().length === 0) {
161
- this.error('XanoScript content is empty');
162
- }
163
- // Load args from JSON file or URL if provided
164
- let inputArgs;
165
- if (flags.args) {
166
- if (this.isUrl(flags.args)) {
167
- try {
168
- const response = await fetch(flags.args);
169
- if (!response.ok) {
170
- this.error(`Failed to fetch args URL: ${response.status} ${response.statusText}`);
171
- }
172
- const argsContent = await response.text();
173
- inputArgs = JSON.parse(argsContent);
174
- }
175
- catch (error) {
176
- this.error(`Failed to fetch or parse args '${flags.args}': ${error}`);
177
- }
178
- }
179
- else {
180
- try {
181
- const argsContent = fs.readFileSync(flags.args, 'utf8');
182
- inputArgs = JSON.parse(argsContent);
183
- }
184
- catch (error) {
185
- this.error(`Failed to read or parse args '${flags.args}': ${error}`);
186
- }
187
- }
188
- }
189
- // Parse env overrides
190
- let envOverrides;
191
- if (flags.env && flags.env.length > 0) {
192
- envOverrides = {};
193
- for (const envStr of flags.env) {
194
- const eqIndex = envStr.indexOf('=');
195
- if (eqIndex === -1) {
196
- this.error(`Invalid env format '${envStr}'. Expected format: key=value`);
197
- }
198
- const key = envStr.slice(0, eqIndex);
199
- const value = envStr.slice(eqIndex + 1);
200
- envOverrides[key] = value;
201
- }
202
- }
203
- // Build query params
204
- const queryParams = {};
205
- if (inputArgs) {
206
- queryParams.args = inputArgs;
207
- }
208
- if (envOverrides) {
209
- queryParams.env = envOverrides;
210
- }
211
- // Execute via API
212
- try {
213
- const url = this.httpClient.buildProjectUrl('/run/exec', queryParams);
214
- const result = await this.httpClient.postXanoScript(url, xanoscript);
215
- // Output results
216
- if (flags.output === 'json') {
217
- this.outputJson(result);
218
- }
219
- else {
220
- this.outputSummary(result);
221
- }
222
- }
223
- catch (error) {
224
- if (error instanceof Error) {
225
- const xanoError = error;
226
- if (xanoError.response) {
227
- const responseStr = typeof xanoError.response === 'string'
228
- ? xanoError.response
229
- : JSON.stringify(xanoError.response, null, 2);
230
- this.error(`Failed to execute: ${error.message}\n\n${responseStr}`);
231
- }
232
- else {
233
- this.error(`Failed to execute: ${error.message}`);
234
- }
235
- }
236
- else {
237
- this.error(`Failed to execute: ${String(error)}`);
238
- }
239
- }
240
- }
241
- /**
242
- * Recursively collect all .xs files from a directory, sorted for deterministic ordering.
243
- */
244
- collectFiles(dir) {
245
- const files = [];
246
- const entries = fs.readdirSync(dir, { withFileTypes: true });
247
- for (const entry of entries) {
248
- const fullPath = path.join(dir, entry.name);
249
- if (entry.isDirectory()) {
250
- files.push(...this.collectFiles(fullPath));
251
- }
252
- else if (entry.isFile() && entry.name.endsWith('.xs')) {
253
- files.push(fullPath);
254
- }
255
- }
256
- return files.sort();
257
- }
258
- // Editor value comes from EDITOR/VISUAL environment variables, not user input
259
- async editFile(filePath) {
260
- const editor = process.env.EDITOR || process.env.VISUAL;
261
- if (!editor) {
262
- this.error('No editor configured. Please set the EDITOR or VISUAL environment variable.\n' +
263
- 'Example: export EDITOR=vim');
264
- }
265
- // Validate editor executable exists
266
- try {
267
- execSync(`which ${editor.split(' ')[0]}`, { stdio: 'ignore' });
268
- }
269
- catch {
270
- this.error(`Editor '${editor}' not found. Please set EDITOR to a valid editor.\n` +
271
- 'Example: export EDITOR=vim');
272
- }
273
- // Read the original file
274
- let originalContent;
275
- try {
276
- originalContent = fs.readFileSync(filePath, 'utf8');
277
- }
278
- catch (error) {
279
- this.error(`Failed to read file '${filePath}': ${error}`);
280
- }
281
- // Create a temporary file with the same extension
282
- const ext = path.extname(filePath);
283
- const tmpFile = path.join(os.tmpdir(), `xano-edit-${Date.now()}${ext}`);
284
- // Copy content to temp file
285
- try {
286
- fs.writeFileSync(tmpFile, originalContent, 'utf8');
287
- }
288
- catch (error) {
289
- this.error(`Failed to create temporary file: ${error}`);
290
- }
291
- // Open the editor
292
- try {
293
- execSync(`${editor} ${tmpFile}`, { stdio: 'inherit' });
294
- }
295
- catch (error) {
296
- try {
297
- fs.unlinkSync(tmpFile);
298
- }
299
- catch {
300
- // Ignore cleanup errors
301
- }
302
- this.error(`Editor exited with an error: ${error}`);
303
- }
304
- return tmpFile;
305
- }
306
- isUrl(str) {
307
- return str.startsWith('http://') || str.startsWith('https://');
308
- }
309
- /**
310
- * Load all .xs files from a directory and combine them into a multidoc.
311
- */
312
- loadMultidocFromDirectory(dir) {
313
- const resolvedDir = path.resolve(dir);
314
- if (!fs.existsSync(resolvedDir)) {
315
- this.error(`Directory not found: ${resolvedDir}`);
316
- }
317
- const files = this.collectFiles(resolvedDir);
318
- if (files.length === 0) {
319
- this.error(`No .xs files found in ${dir}`);
320
- }
321
- // Read each file and join with --- separator
322
- const documents = [];
323
- for (const filePath of files) {
324
- const content = fs.readFileSync(filePath, 'utf8').trim();
325
- if (content) {
326
- documents.push(content);
327
- }
328
- }
329
- if (documents.length === 0) {
330
- this.error(`All .xs files in ${dir} are empty`);
331
- }
332
- return documents.join('\n---\n');
333
- }
334
- outputSummary(result) {
335
- this.log('Executed successfully!');
336
- this.log('');
337
- // Handle service-specific output
338
- if (result.service) {
339
- this.log(` Service ID: ${result.service.id}`);
340
- this.log(` Run ID: ${result.service.run.id}`);
341
- this.log('');
342
- }
343
- // Handle run/session info
344
- if (result.run?.id) {
345
- this.log(` Run ID: ${result.run.id}`);
346
- }
347
- if (result.run?.session) {
348
- const { session } = result.run;
349
- this.log(` Session ID: ${session.id}`);
350
- this.log(` State: ${session.state}`);
351
- this.log('');
352
- }
353
- // Handle timing info
354
- const timing = result.run?.result || result.run?.session || result.result;
355
- if (timing) {
356
- const formatTime = (time) => time === undefined ? undefined : `${(time * 1000).toFixed(2)}ms`;
357
- const times = [
358
- { label: 'Total', value: formatTime(timing.total_time) },
359
- { label: 'Boot', value: formatTime(timing.boot_time) },
360
- { label: 'Main', value: formatTime(timing.main_time) },
361
- { label: 'Pre', value: formatTime(timing.pre_time) },
362
- { label: 'Post', value: formatTime(timing.post_time) },
363
- ].filter(t => t.value !== undefined);
364
- if (times.length > 0) {
365
- this.log(' Timing:');
366
- for (const t of times) {
367
- this.log(` ${t.label.padEnd(6)} ${t.value}`);
368
- }
369
- this.log('');
370
- }
371
- }
372
- // Handle service endpoints
373
- if (result.result?.endpoints && result.result.endpoints.length > 0) {
374
- this.log(' Endpoints:');
375
- for (const endpoint of result.result.endpoints) {
376
- this.log(` ${endpoint.verb.padEnd(6)} ${endpoint.url}`);
377
- if (endpoint.input.length > 0) {
378
- for (const input of endpoint.input) {
379
- const required = input.required ? '*' : '';
380
- const nullable = input.nullable ? '?' : '';
381
- this.log(` └─ ${input.name}${required}: ${input.type}${nullable} (${input.source})`);
382
- }
383
- }
384
- }
385
- this.log('');
386
- }
387
- // Handle metadata API
388
- if (result.result?.metadata_api) {
389
- this.log(' Metadata API:');
390
- this.log(` ${result.result.metadata_api.url}`);
391
- this.log('');
392
- }
393
- // Handle response
394
- const response = result.run?.result?.response ?? result.run?.session?.response ?? result.result?.response;
395
- if (response !== undefined) {
396
- this.log(' Response:');
397
- const responseStr = typeof response === 'string'
398
- ? response
399
- : JSON.stringify(response, null, 2);
400
- const indentedResponse = responseStr.split('\n').map((line) => ` ${line}`).join('\n');
401
- this.log(indentedResponse);
402
- }
403
- // Handle problems/errors
404
- if (result.run?.problems && result.run.problems.length > 0) {
405
- this.log('');
406
- this.log(' Problems:');
407
- for (const problem of result.run.problems) {
408
- this.log(` - [${problem.severity}] ${problem.message}`);
409
- }
410
- }
411
- if (result.run?.session?.error_msg) {
412
- this.log('');
413
- this.log(` Error: ${result.run.session.error_msg}`);
414
- }
415
- }
416
- async readStdin() {
417
- return new Promise((resolve, reject) => {
418
- const chunks = [];
419
- process.stdin.on('data', (chunk) => {
420
- chunks.push(chunk);
421
- });
422
- process.stdin.on('end', () => {
423
- resolve(Buffer.concat(chunks).toString('utf8'));
424
- });
425
- process.stdin.on('error', (error) => {
426
- reject(error);
427
- });
428
- process.stdin.resume();
429
- });
430
- }
431
- }
@@ -1,160 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import * as fs from 'node:fs';
3
- import BaseRunCommand from '../../../lib/base-run-command.js';
4
- export default class RunInfo extends BaseRunCommand {
5
- static args = {};
6
- static description = 'Get information about a XanoScript document (type, inputs, env vars)';
7
- static examples = [
8
- `$ xano run info -f script.xs
9
- Document Info:
10
- Type: job
11
- Inputs:
12
- - name (string, required)
13
- - count (number, optional)
14
- Environment Variables:
15
- - API_KEY
16
- - DEBUG
17
- `,
18
- `$ cat script.xs | xano run info --stdin
19
- Document Info:
20
- Type: service
21
- Inputs: none
22
- Environment Variables: none
23
- `,
24
- `$ xano run info -f script.xs -o json
25
- { "type": "job", "input": { "name": {...} }, "env": ["API_KEY"] }
26
- `,
27
- ];
28
- static flags = {
29
- ...BaseRunCommand.baseFlags,
30
- file: Flags.string({
31
- char: 'f',
32
- description: 'Path or URL to file containing XanoScript code',
33
- exclusive: ['stdin'],
34
- required: false,
35
- }),
36
- output: Flags.string({
37
- char: 'o',
38
- default: 'summary',
39
- description: 'Output format',
40
- options: ['summary', 'json'],
41
- required: false,
42
- }),
43
- stdin: Flags.boolean({
44
- char: 's',
45
- default: false,
46
- description: 'Read XanoScript code from stdin',
47
- exclusive: ['file'],
48
- required: false,
49
- }),
50
- };
51
- async run() {
52
- const { flags } = await this.parse(RunInfo);
53
- // Initialize with project required
54
- await this.initRunCommandWithProject(flags.profile, flags.verbose);
55
- // Read XanoScript content
56
- let xanoscript;
57
- if (flags.file) {
58
- if (this.isUrl(flags.file)) {
59
- // Fetch URL content
60
- try {
61
- const response = await fetch(flags.file);
62
- if (!response.ok) {
63
- this.error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
64
- }
65
- xanoscript = await response.text();
66
- }
67
- catch (error) {
68
- this.error(`Failed to fetch URL '${flags.file}': ${error}`);
69
- }
70
- }
71
- else {
72
- try {
73
- xanoscript = fs.readFileSync(flags.file, 'utf8');
74
- }
75
- catch (error) {
76
- this.error(`Failed to read file '${flags.file}': ${error}`);
77
- }
78
- }
79
- }
80
- else if (flags.stdin) {
81
- try {
82
- xanoscript = await this.readStdin();
83
- }
84
- catch (error) {
85
- this.error(`Failed to read from stdin: ${error}`);
86
- }
87
- }
88
- else {
89
- this.error('Either --file or --stdin must be specified to provide XanoScript code');
90
- }
91
- // Validate xanoscript is not empty
92
- if (!xanoscript || xanoscript.trim().length === 0) {
93
- this.error('XanoScript content is empty');
94
- }
95
- // Get document info via API
96
- try {
97
- const url = this.httpClient.buildProjectUrl('/doc/info');
98
- const result = await this.httpClient.post(url, { doc: xanoscript });
99
- if (flags.output === 'json') {
100
- this.outputJson(result);
101
- }
102
- else {
103
- this.outputSummary(result);
104
- }
105
- }
106
- catch (error) {
107
- if (error instanceof Error) {
108
- this.error(`Failed to get document info: ${error.message}`);
109
- }
110
- else {
111
- this.error(`Failed to get document info: ${String(error)}`);
112
- }
113
- }
114
- }
115
- isUrl(str) {
116
- return str.startsWith('http://') || str.startsWith('https://');
117
- }
118
- outputSummary(result) {
119
- this.log('Document Info:');
120
- this.log(` Type: ${result.type}`);
121
- this.log('');
122
- // Display inputs
123
- this.log(' Inputs:');
124
- if (result.input && Object.keys(result.input).length > 0) {
125
- for (const [name, config] of Object.entries(result.input)) {
126
- const configStr = typeof config === 'object' ? JSON.stringify(config) : String(config);
127
- this.log(` - ${name}: ${configStr}`);
128
- }
129
- }
130
- else {
131
- this.log(' (none)');
132
- }
133
- this.log('');
134
- // Display environment variables
135
- this.log(' Environment Variables:');
136
- if (result.env && result.env.length > 0) {
137
- for (const envVar of result.env) {
138
- this.log(` - ${envVar}`);
139
- }
140
- }
141
- else {
142
- this.log(' (none)');
143
- }
144
- }
145
- async readStdin() {
146
- return new Promise((resolve, reject) => {
147
- const chunks = [];
148
- process.stdin.on('data', (chunk) => {
149
- chunks.push(chunk);
150
- });
151
- process.stdin.on('end', () => {
152
- resolve(Buffer.concat(chunks).toString('utf8'));
153
- });
154
- process.stdin.on('error', (error) => {
155
- reject(error);
156
- });
157
- process.stdin.resume();
158
- });
159
- }
160
- }
@@ -1,75 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import BaseRunCommand from '../../../../lib/base-run-command.js';
3
- export default class RunProjectsCreate extends BaseRunCommand {
4
- static args = {};
5
- static description = 'Create a new project';
6
- static examples = [
7
- `$ xano run projects create -n "My Project"
8
- Project created successfully!
9
- ID: abc123-def456-ghi789
10
- Name: My Project
11
- `,
12
- `$ xano run projects create -n "My Project" -d "Description here"
13
- Project created successfully!
14
- ID: abc123-def456-ghi789
15
- Name: My Project
16
- `,
17
- `$ xano run projects create -n "My Project" -o json
18
- { "id": "abc123-def456-ghi789", "name": "My Project", ... }
19
- `,
20
- ];
21
- static flags = {
22
- ...BaseRunCommand.baseFlags,
23
- description: Flags.string({
24
- char: 'd',
25
- default: '',
26
- description: 'Project description',
27
- required: false,
28
- }),
29
- name: Flags.string({
30
- char: 'n',
31
- description: 'Project name',
32
- required: true,
33
- }),
34
- output: Flags.string({
35
- char: 'o',
36
- default: 'summary',
37
- description: 'Output format',
38
- options: ['summary', 'json'],
39
- required: false,
40
- }),
41
- };
42
- async run() {
43
- const { flags } = await this.parse(RunProjectsCreate);
44
- // Initialize (no project required for creating projects)
45
- await this.initRunCommand(flags.profile, flags.verbose);
46
- const input = {
47
- description: flags.description || '',
48
- name: flags.name,
49
- };
50
- try {
51
- const url = this.httpClient.buildUrl('/project');
52
- const project = await this.httpClient.post(url, input);
53
- if (flags.output === 'json') {
54
- this.outputJson(project);
55
- }
56
- else {
57
- this.log('Project created successfully!');
58
- this.log(` ID: ${project.id}`);
59
- this.log(` Name: ${project.name}`);
60
- if (project.description) {
61
- this.log(` Description: ${project.description}`);
62
- }
63
- this.log(` Access: ${project.access}`);
64
- }
65
- }
66
- catch (error) {
67
- if (error instanceof Error) {
68
- this.error(`Failed to create project: ${error.message}`);
69
- }
70
- else {
71
- this.error(`Failed to create project: ${String(error)}`);
72
- }
73
- }
74
- }
75
- }
@@ -1,14 +0,0 @@
1
- import BaseRunCommand from '../../../../lib/base-run-command.js';
2
- export default class RunProjectsDelete extends BaseRunCommand {
3
- static args: {
4
- projectId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- };
13
- run(): Promise<void>;
14
- }