@xano/cli 0.0.26 → 0.0.28
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/base-command.d.ts +3 -1
- package/dist/base-command.js +12 -5
- package/dist/commands/auth/index.d.ts +21 -0
- package/dist/commands/auth/index.js +533 -0
- package/dist/commands/branch/create/index.d.ts +17 -0
- package/dist/commands/branch/create/index.js +164 -0
- package/dist/commands/branch/delete/index.d.ts +18 -0
- package/dist/commands/branch/delete/index.js +156 -0
- package/dist/commands/branch/edit/index.d.ts +19 -0
- package/dist/commands/branch/edit/index.js +166 -0
- package/dist/commands/branch/get/index.d.ts +16 -0
- package/dist/commands/branch/get/index.js +135 -0
- package/dist/commands/branch/list/index.d.ts +18 -0
- package/dist/commands/branch/list/index.js +138 -0
- package/dist/commands/branch/set-live/index.d.ts +18 -0
- package/dist/commands/branch/set-live/index.js +155 -0
- package/dist/commands/function/create/index.d.ts +7 -6
- package/dist/commands/function/create/index.js +55 -55
- package/dist/commands/function/edit/index.d.ts +11 -10
- package/dist/commands/function/edit/index.js +155 -162
- package/dist/commands/function/get/index.d.ts +6 -5
- package/dist/commands/function/get/index.js +55 -60
- package/dist/commands/function/list/index.d.ts +6 -5
- package/dist/commands/function/list/index.js +52 -52
- package/dist/commands/profile/create/index.d.ts +6 -6
- package/dist/commands/profile/create/index.js +37 -37
- package/dist/commands/profile/delete/index.d.ts +2 -2
- package/dist/commands/profile/delete/index.js +9 -9
- package/dist/commands/profile/edit/index.d.ts +8 -7
- package/dist/commands/profile/edit/index.js +48 -48
- package/dist/commands/profile/get-default/index.js +1 -1
- package/dist/commands/profile/list/index.d.ts +2 -2
- package/dist/commands/profile/list/index.js +9 -9
- package/dist/commands/profile/me/index.d.ts +4 -3
- package/dist/commands/profile/me/index.js +21 -21
- package/dist/commands/profile/project/index.js +1 -1
- package/dist/commands/profile/set-default/index.js +1 -1
- package/dist/commands/profile/token/index.js +1 -1
- package/dist/commands/profile/wizard/index.d.ts +5 -4
- package/dist/commands/profile/wizard/index.js +142 -108
- package/dist/commands/run/env/delete/index.d.ts +3 -2
- package/dist/commands/run/env/delete/index.js +10 -10
- package/dist/commands/run/env/get/index.d.ts +3 -2
- package/dist/commands/run/env/get/index.js +11 -11
- package/dist/commands/run/env/list/index.d.ts +3 -2
- package/dist/commands/run/env/list/index.js +17 -19
- package/dist/commands/run/env/set/index.d.ts +3 -2
- package/dist/commands/run/env/set/index.js +5 -5
- package/dist/commands/run/exec/index.d.ts +19 -8
- package/dist/commands/run/exec/index.js +186 -108
- package/dist/commands/run/info/index.d.ts +5 -4
- package/dist/commands/run/info/index.js +27 -27
- package/dist/commands/run/projects/create/index.d.ts +4 -3
- package/dist/commands/run/projects/create/index.js +23 -23
- package/dist/commands/run/projects/delete/index.d.ts +3 -2
- package/dist/commands/run/projects/delete/index.js +10 -10
- package/dist/commands/run/projects/list/index.d.ts +3 -2
- package/dist/commands/run/projects/list/index.js +12 -12
- package/dist/commands/run/projects/update/index.d.ts +4 -3
- package/dist/commands/run/projects/update/index.js +21 -21
- package/dist/commands/run/secrets/delete/index.d.ts +3 -2
- package/dist/commands/run/secrets/delete/index.js +10 -10
- package/dist/commands/run/secrets/get/index.d.ts +3 -2
- package/dist/commands/run/secrets/get/index.js +11 -11
- package/dist/commands/run/secrets/list/index.d.ts +3 -2
- package/dist/commands/run/secrets/list/index.js +22 -24
- package/dist/commands/run/secrets/set/index.d.ts +4 -3
- package/dist/commands/run/secrets/set/index.js +16 -16
- package/dist/commands/run/sessions/delete/index.d.ts +3 -2
- package/dist/commands/run/sessions/delete/index.js +10 -10
- package/dist/commands/run/sessions/get/index.d.ts +3 -2
- package/dist/commands/run/sessions/get/index.js +11 -11
- package/dist/commands/run/sessions/list/index.d.ts +3 -2
- package/dist/commands/run/sessions/list/index.js +11 -11
- package/dist/commands/run/sessions/start/index.d.ts +3 -2
- package/dist/commands/run/sessions/start/index.js +11 -11
- package/dist/commands/run/sessions/stop/index.d.ts +3 -2
- package/dist/commands/run/sessions/stop/index.js +11 -11
- package/dist/commands/run/sink/get/index.d.ts +3 -2
- package/dist/commands/run/sink/get/index.js +11 -11
- package/dist/commands/static_host/build/create/index.d.ts +5 -4
- package/dist/commands/static_host/build/create/index.js +33 -33
- package/dist/commands/static_host/build/get/index.d.ts +5 -4
- package/dist/commands/static_host/build/get/index.js +20 -20
- package/dist/commands/static_host/build/list/index.d.ts +4 -3
- package/dist/commands/static_host/build/list/index.js +31 -31
- package/dist/commands/static_host/list/index.d.ts +4 -3
- package/dist/commands/static_host/list/index.js +31 -31
- package/dist/commands/workspace/create/index.d.ts +14 -0
- package/dist/commands/workspace/create/index.js +131 -0
- package/dist/commands/workspace/delete/index.d.ts +20 -0
- package/dist/commands/workspace/delete/index.js +141 -0
- package/dist/commands/workspace/edit/index.d.ts +22 -0
- package/dist/commands/workspace/edit/index.js +176 -0
- package/dist/commands/workspace/get/index.d.ts +18 -0
- package/dist/commands/workspace/get/index.js +136 -0
- package/dist/commands/workspace/list/index.d.ts +3 -2
- package/dist/commands/workspace/list/index.js +15 -15
- package/dist/commands/workspace/pull/index.d.ts +6 -4
- package/dist/commands/workspace/pull/index.js +123 -63
- package/dist/commands/workspace/push/index.d.ts +2 -0
- package/dist/commands/workspace/push/index.js +16 -5
- package/dist/help.d.ts +1 -1
- package/dist/lib/base-run-command.d.ts +6 -6
- package/dist/lib/base-run-command.js +8 -6
- package/dist/lib/run-http-client.d.ts +24 -18
- package/dist/lib/run-http-client.js +96 -61
- package/dist/lib/run-types.d.ts +80 -80
- package/oclif.manifest.json +2041 -843
- package/package.json +1 -1
|
@@ -7,16 +7,6 @@ export default class RunEnvGet extends BaseRunCommand {
|
|
|
7
7
|
required: true,
|
|
8
8
|
}),
|
|
9
9
|
};
|
|
10
|
-
static flags = {
|
|
11
|
-
...BaseRunCommand.baseFlags,
|
|
12
|
-
output: Flags.string({
|
|
13
|
-
char: 'o',
|
|
14
|
-
description: 'Output format',
|
|
15
|
-
required: false,
|
|
16
|
-
default: 'value',
|
|
17
|
-
options: ['value', 'json'],
|
|
18
|
-
}),
|
|
19
|
-
};
|
|
20
10
|
static description = 'Get an environment variable value';
|
|
21
11
|
static examples = [
|
|
22
12
|
`$ xano run env get API_KEY
|
|
@@ -26,10 +16,20 @@ my-secret-api-key
|
|
|
26
16
|
{ "name": "API_KEY", "value": "my-secret-api-key" }
|
|
27
17
|
`,
|
|
28
18
|
];
|
|
19
|
+
static flags = {
|
|
20
|
+
...BaseRunCommand.baseFlags,
|
|
21
|
+
output: Flags.string({
|
|
22
|
+
char: 'o',
|
|
23
|
+
default: 'value',
|
|
24
|
+
description: 'Output format',
|
|
25
|
+
options: ['value', 'json'],
|
|
26
|
+
required: false,
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
29
|
async run() {
|
|
30
30
|
const { args, flags } = await this.parse(RunEnvGet);
|
|
31
31
|
// Initialize with project required
|
|
32
|
-
await this.initRunCommandWithProject(flags.profile);
|
|
32
|
+
await this.initRunCommandWithProject(flags.profile, flags.verbose);
|
|
33
33
|
try {
|
|
34
34
|
const url = this.httpClient.buildProjectUrl('/env', { name: args.name });
|
|
35
35
|
const result = await this.httpClient.get(url);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import BaseRunCommand from '../../../../lib/base-run-command.js';
|
|
2
2
|
export default class RunEnvList extends BaseRunCommand {
|
|
3
3
|
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
4
6
|
static flags: {
|
|
5
7
|
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
8
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
10
|
};
|
|
8
|
-
static description: string;
|
|
9
|
-
static examples: string[];
|
|
10
11
|
run(): Promise<void>;
|
|
11
12
|
}
|
|
@@ -2,16 +2,6 @@ import { Flags } from '@oclif/core';
|
|
|
2
2
|
import BaseRunCommand from '../../../../lib/base-run-command.js';
|
|
3
3
|
export default class RunEnvList extends BaseRunCommand {
|
|
4
4
|
static args = {};
|
|
5
|
-
static flags = {
|
|
6
|
-
...BaseRunCommand.baseFlags,
|
|
7
|
-
output: Flags.string({
|
|
8
|
-
char: 'o',
|
|
9
|
-
description: 'Output format',
|
|
10
|
-
required: false,
|
|
11
|
-
default: 'list',
|
|
12
|
-
options: ['list', 'json'],
|
|
13
|
-
}),
|
|
14
|
-
};
|
|
15
5
|
static description = 'List all environment variable keys';
|
|
16
6
|
static examples = [
|
|
17
7
|
`$ xano run env list
|
|
@@ -24,25 +14,33 @@ Environment variables:
|
|
|
24
14
|
{ "env": ["API_KEY", "DATABASE_URL", "DEBUG"] }
|
|
25
15
|
`,
|
|
26
16
|
];
|
|
17
|
+
static flags = {
|
|
18
|
+
...BaseRunCommand.baseFlags,
|
|
19
|
+
output: Flags.string({
|
|
20
|
+
char: 'o',
|
|
21
|
+
default: 'list',
|
|
22
|
+
description: 'Output format',
|
|
23
|
+
options: ['list', 'json'],
|
|
24
|
+
required: false,
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
27
|
async run() {
|
|
28
28
|
const { flags } = await this.parse(RunEnvList);
|
|
29
29
|
// Initialize with project required
|
|
30
|
-
await this.initRunCommandWithProject(flags.profile);
|
|
30
|
+
await this.initRunCommandWithProject(flags.profile, flags.verbose);
|
|
31
31
|
try {
|
|
32
32
|
const url = this.httpClient.buildProjectUrl('/env/key');
|
|
33
33
|
const result = await this.httpClient.get(url);
|
|
34
34
|
if (flags.output === 'json') {
|
|
35
35
|
this.outputJson(result);
|
|
36
36
|
}
|
|
37
|
+
else if (result.env.length === 0) {
|
|
38
|
+
this.log('No environment variables found.');
|
|
39
|
+
}
|
|
37
40
|
else {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
else {
|
|
42
|
-
this.log('Environment variables:');
|
|
43
|
-
for (const key of result.env) {
|
|
44
|
-
this.log(` - ${key}`);
|
|
45
|
-
}
|
|
41
|
+
this.log('Environment variables:');
|
|
42
|
+
for (const key of result.env) {
|
|
43
|
+
this.log(` - ${key}`);
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
}
|
|
@@ -4,10 +4,11 @@ export default class RunEnvSet extends BaseRunCommand {
|
|
|
4
4
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
6
|
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
7
9
|
static flags: {
|
|
8
10
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
12
|
};
|
|
10
|
-
static description: string;
|
|
11
|
-
static examples: string[];
|
|
12
13
|
run(): Promise<void>;
|
|
13
14
|
}
|
|
@@ -11,9 +11,6 @@ export default class RunEnvSet extends BaseRunCommand {
|
|
|
11
11
|
required: true,
|
|
12
12
|
}),
|
|
13
13
|
};
|
|
14
|
-
static flags = {
|
|
15
|
-
...BaseRunCommand.baseFlags,
|
|
16
|
-
};
|
|
17
14
|
static description = 'Set an environment variable';
|
|
18
15
|
static examples = [
|
|
19
16
|
`$ xano run env set API_KEY my-secret-key
|
|
@@ -23,16 +20,19 @@ Environment variable 'API_KEY' set successfully!
|
|
|
23
20
|
Environment variable 'DATABASE_URL' set successfully!
|
|
24
21
|
`,
|
|
25
22
|
];
|
|
23
|
+
static flags = {
|
|
24
|
+
...BaseRunCommand.baseFlags,
|
|
25
|
+
};
|
|
26
26
|
async run() {
|
|
27
27
|
const { args, flags } = await this.parse(RunEnvSet);
|
|
28
28
|
// Initialize with project required
|
|
29
|
-
await this.initRunCommandWithProject(flags.profile);
|
|
29
|
+
await this.initRunCommandWithProject(flags.profile, flags.verbose);
|
|
30
30
|
const input = {
|
|
31
|
-
name: args.name,
|
|
32
31
|
env: {
|
|
33
32
|
name: args.name,
|
|
34
33
|
value: args.value,
|
|
35
34
|
},
|
|
35
|
+
name: args.name,
|
|
36
36
|
};
|
|
37
37
|
try {
|
|
38
38
|
const url = this.httpClient.buildProjectUrl('/env');
|
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
import BaseRunCommand from '../../../lib/base-run-command.js';
|
|
2
2
|
export default class RunExec extends BaseRunCommand {
|
|
3
|
-
static args: {
|
|
3
|
+
static args: {
|
|
4
|
+
path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
4
8
|
static flags: {
|
|
5
|
-
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
-
edit: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
-
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
args: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
edit: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
env: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
15
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
17
|
};
|
|
13
|
-
static description: string;
|
|
14
|
-
static examples: string[];
|
|
15
18
|
run(): Promise<void>;
|
|
16
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Recursively collect all .xs files from a directory, sorted for deterministic ordering.
|
|
21
|
+
*/
|
|
22
|
+
private collectFiles;
|
|
17
23
|
private editFile;
|
|
18
24
|
private isUrl;
|
|
25
|
+
/**
|
|
26
|
+
* Load all .xs files from a directory and combine them into a multidoc.
|
|
27
|
+
*/
|
|
28
|
+
private loadMultidocFromDirectory;
|
|
29
|
+
private outputSummary;
|
|
19
30
|
private readStdin;
|
|
20
31
|
}
|
|
@@ -1,58 +1,28 @@
|
|
|
1
|
-
import { Flags } from '@oclif/core';
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
4
|
import * as os from 'node:os';
|
|
5
5
|
import * as path from 'node:path';
|
|
6
6
|
import BaseRunCommand from '../../../lib/base-run-command.js';
|
|
7
7
|
export default class RunExec extends BaseRunCommand {
|
|
8
|
-
static args = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
file: Flags.string({
|
|
12
|
-
char: 'f',
|
|
13
|
-
description: 'Path or URL to file containing XanoScript code',
|
|
8
|
+
static args = {
|
|
9
|
+
path: Args.string({
|
|
10
|
+
description: 'Path to file or directory containing XanoScript code (directory creates multidoc from .xs files)',
|
|
14
11
|
required: false,
|
|
15
|
-
exclusive: ['stdin'],
|
|
16
|
-
}),
|
|
17
|
-
stdin: Flags.boolean({
|
|
18
|
-
char: 's',
|
|
19
|
-
description: 'Read XanoScript code from stdin',
|
|
20
|
-
required: false,
|
|
21
|
-
default: false,
|
|
22
|
-
exclusive: ['file'],
|
|
23
|
-
}),
|
|
24
|
-
edit: Flags.boolean({
|
|
25
|
-
char: 'e',
|
|
26
|
-
description: 'Open file in editor before running (requires --file)',
|
|
27
|
-
required: false,
|
|
28
|
-
default: false,
|
|
29
|
-
dependsOn: ['file'],
|
|
30
|
-
}),
|
|
31
|
-
output: Flags.string({
|
|
32
|
-
char: 'o',
|
|
33
|
-
description: 'Output format',
|
|
34
|
-
required: false,
|
|
35
|
-
default: 'summary',
|
|
36
|
-
options: ['summary', 'json'],
|
|
37
|
-
}),
|
|
38
|
-
args: Flags.string({
|
|
39
|
-
char: 'a',
|
|
40
|
-
description: 'Path or URL to JSON file containing input arguments',
|
|
41
|
-
required: false,
|
|
42
|
-
}),
|
|
43
|
-
env: Flags.string({
|
|
44
|
-
description: 'Environment variable override (key=value)',
|
|
45
|
-
required: false,
|
|
46
|
-
multiple: true,
|
|
47
12
|
}),
|
|
48
13
|
};
|
|
49
14
|
static description = 'Execute XanoScript code (job or service)';
|
|
50
15
|
static examples = [
|
|
51
|
-
`$ xano run exec
|
|
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
|
|
52
22
|
Executed successfully!
|
|
53
23
|
...
|
|
54
24
|
`,
|
|
55
|
-
`$ xano run exec
|
|
25
|
+
`$ xano run exec script.xs --edit
|
|
56
26
|
# Opens script.xs in $EDITOR, then executes
|
|
57
27
|
Executed successfully!
|
|
58
28
|
...
|
|
@@ -61,45 +31,102 @@ Executed successfully!
|
|
|
61
31
|
Executed successfully!
|
|
62
32
|
...
|
|
63
33
|
`,
|
|
64
|
-
`$ xano run exec
|
|
34
|
+
`$ xano run exec script.xs -o json
|
|
65
35
|
{
|
|
66
36
|
"run": { ... }
|
|
67
37
|
}
|
|
68
38
|
`,
|
|
69
|
-
`$ xano run exec
|
|
39
|
+
`$ xano run exec script.xs -a args.json
|
|
70
40
|
# Executes with input arguments from args.json
|
|
71
41
|
Executed successfully!
|
|
72
42
|
...
|
|
73
43
|
`,
|
|
74
|
-
`$ xano run exec
|
|
44
|
+
`$ xano run exec script.xs --env API_KEY=secret --env DEBUG=true
|
|
75
45
|
# Executes with environment variable overrides
|
|
76
46
|
Executed successfully!
|
|
77
47
|
...
|
|
78
48
|
`,
|
|
79
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
|
+
};
|
|
80
89
|
async run() {
|
|
81
|
-
const { flags } = await this.parse(RunExec);
|
|
90
|
+
const { args, flags } = await this.parse(RunExec);
|
|
82
91
|
// Initialize with project required
|
|
83
|
-
await this.initRunCommandWithProject(flags.profile);
|
|
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
|
+
}
|
|
84
107
|
// Read XanoScript content
|
|
85
108
|
let xanoscript;
|
|
86
|
-
if (
|
|
87
|
-
if (this.isUrl(
|
|
109
|
+
if (inputPath) {
|
|
110
|
+
if (this.isUrl(inputPath)) {
|
|
88
111
|
// Fetch URL content
|
|
89
112
|
try {
|
|
90
|
-
const response = await fetch(
|
|
113
|
+
const response = await fetch(inputPath);
|
|
91
114
|
if (!response.ok) {
|
|
92
115
|
this.error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
|
|
93
116
|
}
|
|
94
117
|
xanoscript = await response.text();
|
|
95
118
|
}
|
|
96
119
|
catch (error) {
|
|
97
|
-
this.error(`Failed to fetch URL '${
|
|
120
|
+
this.error(`Failed to fetch URL '${inputPath}': ${error}`);
|
|
98
121
|
}
|
|
99
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
|
+
}
|
|
100
127
|
else if (flags.edit) {
|
|
101
128
|
// If edit flag is set, copy to temp file and open in editor
|
|
102
|
-
const fileToRead = await this.editFile(
|
|
129
|
+
const fileToRead = await this.editFile(inputPath);
|
|
103
130
|
xanoscript = fs.readFileSync(fileToRead, 'utf8');
|
|
104
131
|
// Clean up temp file
|
|
105
132
|
try {
|
|
@@ -111,10 +138,10 @@ Executed successfully!
|
|
|
111
138
|
}
|
|
112
139
|
else {
|
|
113
140
|
try {
|
|
114
|
-
xanoscript = fs.readFileSync(
|
|
141
|
+
xanoscript = fs.readFileSync(inputPath, 'utf8');
|
|
115
142
|
}
|
|
116
143
|
catch (error) {
|
|
117
|
-
this.error(`Failed to read file '${
|
|
144
|
+
this.error(`Failed to read file '${inputPath}': ${error}`);
|
|
118
145
|
}
|
|
119
146
|
}
|
|
120
147
|
}
|
|
@@ -127,7 +154,7 @@ Executed successfully!
|
|
|
127
154
|
}
|
|
128
155
|
}
|
|
129
156
|
else {
|
|
130
|
-
this.error('Either --file or --stdin must be specified to provide XanoScript code');
|
|
157
|
+
this.error('Either a path argument, --file, or --stdin must be specified to provide XanoScript code');
|
|
131
158
|
}
|
|
132
159
|
// Validate xanoscript is not empty
|
|
133
160
|
if (!xanoscript || xanoscript.trim().length === 0) {
|
|
@@ -195,13 +222,115 @@ Executed successfully!
|
|
|
195
222
|
}
|
|
196
223
|
catch (error) {
|
|
197
224
|
if (error instanceof Error) {
|
|
198
|
-
|
|
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
|
+
}
|
|
199
235
|
}
|
|
200
236
|
else {
|
|
201
237
|
this.error(`Failed to execute: ${String(error)}`);
|
|
202
238
|
}
|
|
203
239
|
}
|
|
204
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
|
+
}
|
|
205
334
|
outputSummary(result) {
|
|
206
335
|
this.log('Executed successfully!');
|
|
207
336
|
this.log('');
|
|
@@ -216,7 +345,7 @@ Executed successfully!
|
|
|
216
345
|
this.log(` Run ID: ${result.run.id}`);
|
|
217
346
|
}
|
|
218
347
|
if (result.run?.session) {
|
|
219
|
-
const session = result.run
|
|
348
|
+
const { session } = result.run;
|
|
220
349
|
this.log(` Session ID: ${session.id}`);
|
|
221
350
|
this.log(` State: ${session.state}`);
|
|
222
351
|
this.log('');
|
|
@@ -224,7 +353,7 @@ Executed successfully!
|
|
|
224
353
|
// Handle timing info
|
|
225
354
|
const timing = result.run?.result || result.run?.session || result.result;
|
|
226
355
|
if (timing) {
|
|
227
|
-
const formatTime = (time) => time
|
|
356
|
+
const formatTime = (time) => time === undefined ? undefined : `${(time * 1000).toFixed(2)}ms`;
|
|
228
357
|
const times = [
|
|
229
358
|
{ label: 'Total', value: formatTime(timing.total_time) },
|
|
230
359
|
{ label: 'Boot', value: formatTime(timing.boot_time) },
|
|
@@ -284,57 +413,6 @@ Executed successfully!
|
|
|
284
413
|
this.log(` Error: ${result.run.session.error_msg}`);
|
|
285
414
|
}
|
|
286
415
|
}
|
|
287
|
-
// Editor value comes from EDITOR/VISUAL environment variables, not user input
|
|
288
|
-
async editFile(filePath) {
|
|
289
|
-
const editor = process.env.EDITOR || process.env.VISUAL;
|
|
290
|
-
if (!editor) {
|
|
291
|
-
this.error('No editor configured. Please set the EDITOR or VISUAL environment variable.\n' +
|
|
292
|
-
'Example: export EDITOR=vim');
|
|
293
|
-
}
|
|
294
|
-
// Validate editor executable exists
|
|
295
|
-
try {
|
|
296
|
-
execSync(`which ${editor.split(' ')[0]}`, { stdio: 'ignore' });
|
|
297
|
-
}
|
|
298
|
-
catch {
|
|
299
|
-
this.error(`Editor '${editor}' not found. Please set EDITOR to a valid editor.\n` +
|
|
300
|
-
'Example: export EDITOR=vim');
|
|
301
|
-
}
|
|
302
|
-
// Read the original file
|
|
303
|
-
let originalContent;
|
|
304
|
-
try {
|
|
305
|
-
originalContent = fs.readFileSync(filePath, 'utf8');
|
|
306
|
-
}
|
|
307
|
-
catch (error) {
|
|
308
|
-
this.error(`Failed to read file '${filePath}': ${error}`);
|
|
309
|
-
}
|
|
310
|
-
// Create a temporary file with the same extension
|
|
311
|
-
const ext = path.extname(filePath);
|
|
312
|
-
const tmpFile = path.join(os.tmpdir(), `xano-edit-${Date.now()}${ext}`);
|
|
313
|
-
// Copy content to temp file
|
|
314
|
-
try {
|
|
315
|
-
fs.writeFileSync(tmpFile, originalContent, 'utf8');
|
|
316
|
-
}
|
|
317
|
-
catch (error) {
|
|
318
|
-
this.error(`Failed to create temporary file: ${error}`);
|
|
319
|
-
}
|
|
320
|
-
// Open the editor
|
|
321
|
-
try {
|
|
322
|
-
execSync(`${editor} ${tmpFile}`, { stdio: 'inherit' });
|
|
323
|
-
}
|
|
324
|
-
catch (error) {
|
|
325
|
-
try {
|
|
326
|
-
fs.unlinkSync(tmpFile);
|
|
327
|
-
}
|
|
328
|
-
catch {
|
|
329
|
-
// Ignore cleanup errors
|
|
330
|
-
}
|
|
331
|
-
this.error(`Editor exited with an error: ${error}`);
|
|
332
|
-
}
|
|
333
|
-
return tmpFile;
|
|
334
|
-
}
|
|
335
|
-
isUrl(str) {
|
|
336
|
-
return str.startsWith('http://') || str.startsWith('https://');
|
|
337
|
-
}
|
|
338
416
|
async readStdin() {
|
|
339
417
|
return new Promise((resolve, reject) => {
|
|
340
418
|
const chunks = [];
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import BaseRunCommand from '../../../lib/base-run-command.js';
|
|
2
2
|
export default class RunInfo extends BaseRunCommand {
|
|
3
3
|
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
4
6
|
static flags: {
|
|
5
7
|
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
8
|
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
10
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
12
|
};
|
|
10
|
-
static description: string;
|
|
11
|
-
static examples: string[];
|
|
12
13
|
run(): Promise<void>;
|
|
13
|
-
private outputSummary;
|
|
14
14
|
private isUrl;
|
|
15
|
+
private outputSummary;
|
|
15
16
|
private readStdin;
|
|
16
17
|
}
|