@appliance.sh/cli 1.9.0 → 1.10.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/package.json +2 -2
- package/src/appliance-configure.ts +47 -9
- package/src/utils/common.ts +16 -2
- package/src/wizards/appliance.ts +33 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appliance.sh/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Shell for installing, running, and developing applications on the Appliance platform",
|
|
5
5
|
"repository": "https://github.com/appliance-sh/appliance.sh",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@appliance.sh/sdk": "1.
|
|
20
|
+
"@appliance.sh/sdk": "1.10.0",
|
|
21
21
|
"@inquirer/prompts": "^7.10.1",
|
|
22
22
|
"chalk": "^5.4.1",
|
|
23
23
|
"commander": "^14.0.0",
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { extractApplianceFile } from './utils/common.js';
|
|
3
|
-
import {
|
|
2
|
+
import { extractApplianceFile, saveApplianceFile } from './utils/common.js';
|
|
3
|
+
import {
|
|
4
|
+
promptForApplianceFramework,
|
|
5
|
+
promptForApplianceName,
|
|
6
|
+
promptForAppliancePort,
|
|
7
|
+
promptForApplianceType,
|
|
8
|
+
} from './wizards/appliance.js';
|
|
4
9
|
import * as diff from 'json-diff';
|
|
5
10
|
|
|
6
11
|
import * as prompt from '@inquirer/prompts';
|
|
12
|
+
import { ApplianceInput, ApplianceType } from '@appliance.sh/sdk';
|
|
7
13
|
|
|
8
14
|
const program = new Command();
|
|
9
15
|
|
|
@@ -13,37 +19,69 @@ program
|
|
|
13
19
|
|
|
14
20
|
const cmd = program.parse(process.argv);
|
|
15
21
|
|
|
16
|
-
const
|
|
22
|
+
const applianceFileResult = extractApplianceFile(cmd);
|
|
17
23
|
|
|
18
24
|
// If a file or directory was specified, but the file was not found, exit with an error.
|
|
19
25
|
if (
|
|
20
26
|
((cmd.getOptionValue('file') && cmd.getOptionValue('file') !== 'appliance.json') ||
|
|
21
27
|
cmd.getOptionValue('directory')) &&
|
|
22
|
-
!
|
|
28
|
+
!applianceFileResult.success
|
|
23
29
|
) {
|
|
24
30
|
console.log('The specified file was not found.');
|
|
25
31
|
process.exit(1);
|
|
26
32
|
}
|
|
27
33
|
|
|
34
|
+
if (!applianceFileResult.success) {
|
|
35
|
+
console.log(`An error occurred while reading the specified file.`);
|
|
36
|
+
console.log(applianceFileResult.error);
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
let updatedApplianceFile = {
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
manifest: 'v1',
|
|
41
|
+
...applianceFileResult.data,
|
|
42
|
+
} as ApplianceInput;
|
|
31
43
|
|
|
32
44
|
try {
|
|
33
|
-
const name = await promptForApplianceName(
|
|
45
|
+
const name = await promptForApplianceName(updatedApplianceFile);
|
|
34
46
|
|
|
35
47
|
updatedApplianceFile = {
|
|
36
|
-
name,
|
|
37
48
|
...updatedApplianceFile,
|
|
49
|
+
name,
|
|
38
50
|
};
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
const type = await promptForApplianceType(updatedApplianceFile);
|
|
53
|
+
|
|
54
|
+
if (type === ApplianceType.framework) {
|
|
55
|
+
const framework = await promptForApplianceFramework(updatedApplianceFile);
|
|
56
|
+
updatedApplianceFile = {
|
|
57
|
+
...updatedApplianceFile,
|
|
58
|
+
type,
|
|
59
|
+
framework,
|
|
60
|
+
};
|
|
61
|
+
} else if (type === ApplianceType.container) {
|
|
62
|
+
const port = await promptForAppliancePort(updatedApplianceFile);
|
|
63
|
+
|
|
64
|
+
updatedApplianceFile = {
|
|
65
|
+
...updatedApplianceFile,
|
|
66
|
+
type,
|
|
67
|
+
port,
|
|
68
|
+
};
|
|
69
|
+
} else {
|
|
70
|
+
updatedApplianceFile = {
|
|
71
|
+
...updatedApplianceFile,
|
|
72
|
+
type,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log(diff.colorize(diff.diff(applianceFileResult.data, updatedApplianceFile)));
|
|
41
77
|
|
|
42
78
|
const saveChanges = await prompt.confirm({ message: 'Save changes?', default: true });
|
|
43
79
|
if (!saveChanges) {
|
|
44
80
|
console.log('Changes cancelled.');
|
|
45
81
|
process.exit(0);
|
|
46
82
|
}
|
|
83
|
+
|
|
84
|
+
saveApplianceFile(cmd.getOptionValue('file') || 'appliance.json', updatedApplianceFile);
|
|
47
85
|
} catch (error) {
|
|
48
86
|
console.error(error);
|
|
49
87
|
}
|
package/src/utils/common.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
|
-
import { applianceInput, ApplianceInput, Result } from '@appliance.sh/sdk';
|
|
4
|
+
import { Appliance, applianceInput, ApplianceInput, Result } from '@appliance.sh/sdk';
|
|
5
5
|
|
|
6
6
|
export function extractApplianceFile(cmd: Command): Result<ApplianceInput> {
|
|
7
7
|
let filePath;
|
|
@@ -25,7 +25,7 @@ export function extractApplianceFile(cmd: Command): Result<ApplianceInput> {
|
|
|
25
25
|
|
|
26
26
|
try {
|
|
27
27
|
const fileBuf = fs.readFileSync(filePath);
|
|
28
|
-
const result = applianceInput.safeParse(fileBuf.toString());
|
|
28
|
+
const result = applianceInput.safeParse(JSON.parse(fileBuf.toString()));
|
|
29
29
|
|
|
30
30
|
return result;
|
|
31
31
|
} catch (err) {
|
|
@@ -35,3 +35,17 @@ export function extractApplianceFile(cmd: Command): Result<ApplianceInput> {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
export function saveApplianceFile(filePath: string, appliance: Appliance) {
|
|
40
|
+
try {
|
|
41
|
+
fs.writeFileSync(filePath, JSON.stringify(appliance, null, 2));
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
};
|
|
45
|
+
} catch (err) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
error: err as Error,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/wizards/appliance.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as prompts from '@inquirer/prompts';
|
|
2
|
-
import { ApplianceInput } from '@appliance.sh/sdk';
|
|
2
|
+
import { ApplianceFramework, ApplianceInput, ApplianceType } from '@appliance.sh/sdk';
|
|
3
3
|
import * as slug from 'random-word-slugs';
|
|
4
4
|
|
|
5
5
|
export const promptForApplianceName = (config?: Partial<ApplianceInput>) => {
|
|
@@ -10,3 +10,35 @@ export const promptForApplianceName = (config?: Partial<ApplianceInput>) => {
|
|
|
10
10
|
|
|
11
11
|
return name;
|
|
12
12
|
};
|
|
13
|
+
|
|
14
|
+
export const promptForApplianceType = (config: Partial<ApplianceInput>) => {
|
|
15
|
+
const type = prompts.select<ApplianceType>({
|
|
16
|
+
message: `Choose a type:`,
|
|
17
|
+
choices: [ApplianceType.framework, ApplianceType.container],
|
|
18
|
+
default: config?.type ?? ApplianceType.framework,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return type;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const promptForApplianceFramework = (config: Partial<ApplianceInput>) => {
|
|
25
|
+
const framework = prompts.select<ApplianceFramework>({
|
|
26
|
+
message: `Choose a framework:`,
|
|
27
|
+
choices: [ApplianceFramework.Auto, ApplianceFramework.Node, ApplianceFramework.Python],
|
|
28
|
+
default: (config.type === ApplianceType.framework ? config.framework : undefined) ?? ApplianceFramework.Auto,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return framework;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const promptForAppliancePort = (config: Partial<ApplianceInput>) => {
|
|
35
|
+
const port = prompts.number<true>({
|
|
36
|
+
message: 'What port should the app listen on?',
|
|
37
|
+
min: 1,
|
|
38
|
+
max: 65535,
|
|
39
|
+
validate: (value) => !isNaN(parseInt(`${value}`)) || 'Please enter a valid port number',
|
|
40
|
+
default: (config.type === ApplianceType.container ? config.port : undefined) ?? 8080,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return port;
|
|
44
|
+
};
|