sitevision-cli 0.3.1-beta.1 → 0.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +1 -2
- package/dist/app.js +19 -14
- package/dist/cli.js +76 -24
- package/dist/commands/build.d.ts +1 -1
- package/dist/commands/build.js +8 -32
- package/dist/commands/deploy.js +19 -20
- package/dist/commands/dev.js +12 -32
- package/dist/commands/index.js +1 -1
- package/dist/commands/info.js +3 -53
- package/dist/commands/setup-signing.js +2 -2
- package/dist/commands/sign.d.ts +1 -1
- package/dist/commands/sign.js +14 -20
- package/dist/components/DevPropertiesForm.d.ts +1 -2
- package/dist/components/DevPropertiesForm.js +15 -30
- package/dist/components/InfoScreen.d.ts +1 -2
- package/dist/components/InfoScreen.js +2 -50
- package/dist/components/MainMenu.d.ts +1 -2
- package/dist/components/MainMenu.js +5 -70
- package/dist/components/PasswordInput.d.ts +1 -2
- package/dist/components/PasswordInput.js +7 -19
- package/dist/components/ProcessOutput.d.ts +1 -2
- package/dist/components/ProcessOutput.js +3 -5
- package/dist/components/SetupFlow.d.ts +1 -2
- package/dist/components/SetupFlow.js +12 -87
- package/dist/components/SigningPropertiesForm.d.ts +1 -2
- package/dist/components/SigningPropertiesForm.js +7 -18
- package/dist/components/StatusIndicator.d.ts +1 -2
- package/dist/components/StatusIndicator.js +6 -12
- package/dist/components/TextInput.d.ts +1 -2
- package/dist/components/TextInput.js +5 -13
- package/dist/components/WelcomeScreen.d.ts +14 -0
- package/dist/components/WelcomeScreen.js +53 -0
- package/dist/utils/branding.d.ts +12 -0
- package/dist/utils/branding.js +29 -0
- package/dist/utils/config.d.ts +17 -0
- package/dist/utils/config.js +57 -0
- package/dist/utils/password-prompt.js +2 -2
- package/dist/utils/process-runner.d.ts +6 -6
- package/dist/utils/process-runner.js +12 -42
- package/dist/utils/project-detection.d.ts +1 -1
- package/dist/utils/project-detection.js +7 -3
- package/dist/utils/sitevision-api.js +1 -1
- package/dist/utils/version-check.js +3 -3
- package/dist/utils/webpack-runner.d.ts +2 -2
- package/dist/utils/webpack-runner.js +15 -42
- package/dist/utils/zip.js +5 -7
- package/package.json +23 -30
- package/readme.md +11 -7
package/dist/app.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { type ProjectInfo } from './utils/project-detection.js';
|
|
3
2
|
type Props = {
|
|
4
3
|
project: ProjectInfo;
|
|
5
4
|
};
|
|
6
|
-
export default function App({ project }: Props):
|
|
5
|
+
export default function App({ project }: Props): import("react").JSX.Element | null;
|
|
7
6
|
export {};
|
package/dist/app.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
2
3
|
import { MainMenu } from './components/MainMenu.js';
|
|
3
4
|
import { InfoScreen } from './components/InfoScreen.js';
|
|
4
5
|
import { SetupFlow } from './components/SetupFlow.js';
|
|
@@ -8,7 +9,7 @@ import { BuildScreen } from './commands/build.js';
|
|
|
8
9
|
import { DeployScreen } from './commands/deploy.js';
|
|
9
10
|
import { SignScreen } from './commands/sign.js';
|
|
10
11
|
import { SigningPropertiesForm } from './components/SigningPropertiesForm.js';
|
|
11
|
-
import { setDeployPassword as saveDeployPassword, setSigningPassword as saveSigningPassword } from './utils/keychain.js';
|
|
12
|
+
import { setDeployPassword as saveDeployPassword, setSigningPassword as saveSigningPassword, } from './utils/keychain.js';
|
|
12
13
|
export default function App({ project }) {
|
|
13
14
|
const [state, setState] = useState('setup');
|
|
14
15
|
const [currentCommand, setCurrentCommand] = useState('');
|
|
@@ -26,7 +27,10 @@ export default function App({ project }) {
|
|
|
26
27
|
};
|
|
27
28
|
const handleDevPasswordSubmit = (password, remember) => {
|
|
28
29
|
setDevPassword(password);
|
|
29
|
-
if (remember &&
|
|
30
|
+
if (remember &&
|
|
31
|
+
project.devProperties?.domain &&
|
|
32
|
+
project.devProperties.username &&
|
|
33
|
+
password) {
|
|
30
34
|
saveDeployPassword(project.devProperties.domain, project.devProperties.username, password);
|
|
31
35
|
}
|
|
32
36
|
// Continue to the intended command
|
|
@@ -131,22 +135,22 @@ export default function App({ project }) {
|
|
|
131
135
|
}
|
|
132
136
|
};
|
|
133
137
|
if (state === 'setup') {
|
|
134
|
-
return
|
|
138
|
+
return _jsx(SetupFlow, { project: project, onComplete: () => setState('menu') });
|
|
135
139
|
}
|
|
136
140
|
if (state === 'menu') {
|
|
137
|
-
return
|
|
141
|
+
return _jsx(MainMenu, { project: project, onSelect: handleCommandSelect });
|
|
138
142
|
}
|
|
139
143
|
if (state === 'info') {
|
|
140
|
-
return
|
|
144
|
+
return _jsx(InfoScreen, { project: project, onBack: () => setState('menu') });
|
|
141
145
|
}
|
|
142
146
|
if (state === 'dev-password-input') {
|
|
143
|
-
return (
|
|
147
|
+
return (_jsx(PasswordInput, { label: "Enter Development Password (usually Sitevision Cloud Password)", showRememberOption: Boolean(project.devProperties?.domain && project.devProperties?.username), onSubmit: handleDevPasswordSubmit, onCancel: () => setState('menu') }, "dev-password"));
|
|
144
148
|
}
|
|
145
149
|
if (state === 'signing-password-input') {
|
|
146
|
-
return (
|
|
150
|
+
return (_jsx(PasswordInput, { label: "Enter Signing Password (developer.sitevision.se)", showRememberOption: Boolean(project.devProperties?.signingUsername), onSubmit: handleSigningPasswordSubmit, onCancel: () => setState('menu') }, "signing-password"));
|
|
147
151
|
}
|
|
148
152
|
if (state === 'dev') {
|
|
149
|
-
return (
|
|
153
|
+
return (_jsx(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: getEffectiveDevProperties(), signed: currentCommand === 'dev-signed', onBack: () => setState('menu'), onRetryCredentials: () => {
|
|
150
154
|
setDevPassword('');
|
|
151
155
|
if (project.devProperties)
|
|
152
156
|
project.devProperties.password = undefined;
|
|
@@ -154,7 +158,8 @@ export default function App({ project }) {
|
|
|
154
158
|
setSigningPassword('');
|
|
155
159
|
}
|
|
156
160
|
setState('dev-password-input');
|
|
157
|
-
}, signingCredentials: currentCommand === 'dev-signed' &&
|
|
161
|
+
}, signingCredentials: currentCommand === 'dev-signed' &&
|
|
162
|
+
project.devProperties?.signingUsername
|
|
158
163
|
? {
|
|
159
164
|
username: project.devProperties.signingUsername,
|
|
160
165
|
password: signingPassword,
|
|
@@ -163,16 +168,16 @@ export default function App({ project }) {
|
|
|
163
168
|
: undefined }));
|
|
164
169
|
}
|
|
165
170
|
if (state === 'build') {
|
|
166
|
-
return (
|
|
171
|
+
return (_jsx(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: true, onBack: () => setState('menu') }));
|
|
167
172
|
}
|
|
168
173
|
if (state === 'sign') {
|
|
169
|
-
return (
|
|
174
|
+
return (_jsx(SignScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, password: signingPassword, onBack: () => setState('menu'), onRetryCredentials: () => {
|
|
170
175
|
setSigningPassword('');
|
|
171
176
|
setState('signing-password-input');
|
|
172
177
|
} }));
|
|
173
178
|
}
|
|
174
179
|
if (state === 'deploy') {
|
|
175
|
-
return (
|
|
180
|
+
return (_jsx(DeployScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: getEffectiveDevProperties(), force: currentCommand === 'deploy-force', production: currentCommand === 'deploy-production', activate: currentCommand === 'deploy-production', onBack: () => setState('menu'), onRetryCredentials: () => {
|
|
176
181
|
setDevPassword('');
|
|
177
182
|
if (project.devProperties)
|
|
178
183
|
project.devProperties.password = undefined;
|
|
@@ -180,7 +185,7 @@ export default function App({ project }) {
|
|
|
180
185
|
} }));
|
|
181
186
|
}
|
|
182
187
|
if (state === 'setup-signing') {
|
|
183
|
-
return (
|
|
188
|
+
return (_jsx(SigningPropertiesForm, { projectRoot: project.root, onComplete: () => {
|
|
184
189
|
// We can't easily update project info here without full reload,
|
|
185
190
|
// but since we are just returning to menu, it's fine.
|
|
186
191
|
// The user might need to restart CLI or we implement a reload mechanism.
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { render } from 'ink';
|
|
4
4
|
import { Text, Box } from 'ink';
|
|
5
5
|
import meow from 'meow';
|
|
6
6
|
import { readFileSync } from 'node:fs';
|
|
7
7
|
import App from './app.js';
|
|
8
8
|
import { getCommand } from './commands/index.js';
|
|
9
|
-
import { requireProject, migrateLegacyPassword } from './utils/project-detection.js';
|
|
9
|
+
import { requireProject, migrateLegacyPassword, } from './utils/project-detection.js';
|
|
10
10
|
import { promptYesNo } from './utils/password-prompt.js';
|
|
11
11
|
import { checkForUpdate } from './utils/version-check.js';
|
|
12
|
+
import { isFirstRun, markFirstRunComplete, getLastSeenVersion, setLastSeenVersion, } from './utils/config.js';
|
|
13
|
+
import { WelcomeScreen } from './components/WelcomeScreen.js';
|
|
14
|
+
import { printBranding } from './utils/branding.js';
|
|
12
15
|
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
13
16
|
const cli = meow(`
|
|
14
17
|
Usage
|
|
@@ -42,23 +45,71 @@ const cli = meow(`
|
|
|
42
45
|
},
|
|
43
46
|
force: {
|
|
44
47
|
type: 'boolean',
|
|
45
|
-
|
|
48
|
+
shortFlag: 'f',
|
|
46
49
|
default: false,
|
|
47
50
|
},
|
|
48
51
|
production: {
|
|
49
52
|
type: 'boolean',
|
|
50
|
-
|
|
53
|
+
shortFlag: 'p',
|
|
51
54
|
default: false,
|
|
52
55
|
},
|
|
53
56
|
},
|
|
54
57
|
});
|
|
55
58
|
const [commandName, ...args] = cli.input;
|
|
59
|
+
const CYAN = '\x1b[36m';
|
|
60
|
+
const BOLD = '\x1b[1m';
|
|
61
|
+
const DIM = '\x1b[2m';
|
|
62
|
+
const RESET = '\x1b[0m';
|
|
63
|
+
// Visible column width of a string: astral code points (emoji) take 2 columns,
|
|
64
|
+
// everything else 1. ANSI escapes are never passed in here.
|
|
65
|
+
function displayWidth(text) {
|
|
66
|
+
let width = 0;
|
|
67
|
+
for (const char of text) {
|
|
68
|
+
width += (char.codePointAt(0) ?? 0) > 0xffff ? 2 : 1;
|
|
69
|
+
}
|
|
70
|
+
return width;
|
|
71
|
+
}
|
|
72
|
+
// Print a boxed masthead. Borders are sized from the content's display width so
|
|
73
|
+
// they stay aligned regardless of how long the version string is.
|
|
74
|
+
function printMasthead(version) {
|
|
75
|
+
const left = '📦 Sitevision CLI';
|
|
76
|
+
const right = `v${version}`;
|
|
77
|
+
const padding = 2; // spaces inside each vertical border
|
|
78
|
+
const gap = 7; // spaces between the title and the version
|
|
79
|
+
const inner = padding + displayWidth(left) + gap + displayWidth(right) + padding;
|
|
80
|
+
const border = '─'.repeat(inner);
|
|
81
|
+
const spaces = (n) => ' '.repeat(n);
|
|
82
|
+
console.log(`${CYAN}╭${border}╮${RESET}`);
|
|
83
|
+
console.log(`${CYAN}│${RESET}${spaces(padding)}${BOLD}${CYAN}${left}${RESET}` +
|
|
84
|
+
`${spaces(gap)}${DIM}${right}${RESET}${spaces(padding)}${CYAN}│${RESET}`);
|
|
85
|
+
console.log(`${CYAN}╰${border}╯${RESET}`);
|
|
86
|
+
}
|
|
56
87
|
async function main() {
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
// On the very first run we show a dedicated welcome screen instead of the
|
|
89
|
+
// masthead, so the branding is the moment. Only when stdin is a TTY — the
|
|
90
|
+
// welcome is interactive and would hang in CI / piped input.
|
|
91
|
+
const firstRun = isFirstRun() && Boolean(process.stdin.isTTY);
|
|
92
|
+
// On a version bump (but not the very first run) show a "what's new" banner
|
|
93
|
+
// with the logo. `lastSeen` is undefined for fresh installs and for users
|
|
94
|
+
// who predate version tracking — in both cases we record the version
|
|
95
|
+
// silently rather than claiming an update happened.
|
|
96
|
+
const lastSeen = getLastSeenVersion();
|
|
97
|
+
const isUpdate = !firstRun && lastSeen !== undefined && lastSeen !== pkg.version;
|
|
98
|
+
if (!firstRun) {
|
|
99
|
+
if (isUpdate) {
|
|
100
|
+
printBranding();
|
|
101
|
+
console.log(`\x1b[32m\n ✨ Updated to v${pkg.version}\x1b[0m \x1b[2m(from v${lastSeen})\x1b[0m\n`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
printMasthead(pkg.version);
|
|
105
|
+
}
|
|
106
|
+
// Record the current version so the banner shows once per upgrade.
|
|
107
|
+
setLastSeenVersion(pkg.version);
|
|
108
|
+
// Check npm for a newer published release.
|
|
109
|
+
const latestVersion = await checkForUpdate(pkg.name, pkg.version);
|
|
110
|
+
if (latestVersion) {
|
|
111
|
+
console.log(`\x1b[33m ↑ update available: ${pkg.version} → ${latestVersion} (run: npm i -g ${pkg.name})\x1b[0m`);
|
|
112
|
+
}
|
|
62
113
|
}
|
|
63
114
|
// Check if we're in a Sitevision project
|
|
64
115
|
const project = (() => {
|
|
@@ -66,30 +117,31 @@ async function main() {
|
|
|
66
117
|
return requireProject();
|
|
67
118
|
}
|
|
68
119
|
catch (error) {
|
|
69
|
-
render(
|
|
70
|
-
React.createElement(Text, { color: "red" },
|
|
71
|
-
"Error: ",
|
|
72
|
-
error.message),
|
|
73
|
-
React.createElement(Text, { dimColor: true }, "Make sure you're in a Sitevision project directory")));
|
|
120
|
+
render(_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { color: "red", children: ["Error: ", error.message] }), _jsx(Text, { dimColor: true, children: "Make sure you're in a Sitevision project directory" })] }));
|
|
74
121
|
process.exit(1);
|
|
75
122
|
}
|
|
76
123
|
})();
|
|
124
|
+
// First run: show the welcome (branding + optional signing-password save),
|
|
125
|
+
// then continue to the normal flow once the user dismisses it.
|
|
126
|
+
if (firstRun) {
|
|
127
|
+
await new Promise(resolve => {
|
|
128
|
+
const app = render(_jsx(WelcomeScreen, { project: project, onComplete: () => {
|
|
129
|
+
markFirstRunComplete();
|
|
130
|
+
setLastSeenVersion(pkg.version);
|
|
131
|
+
app.unmount();
|
|
132
|
+
} }));
|
|
133
|
+
app.waitUntilExit().then(() => resolve(), () => resolve());
|
|
134
|
+
});
|
|
135
|
+
}
|
|
77
136
|
// If no command, show interactive menu
|
|
78
137
|
if (!commandName) {
|
|
79
|
-
render(
|
|
138
|
+
render(_jsx(App, { project: project }));
|
|
80
139
|
return;
|
|
81
140
|
}
|
|
82
141
|
// Get the command
|
|
83
142
|
const command = getCommand(commandName);
|
|
84
143
|
if (!command) {
|
|
85
|
-
render(
|
|
86
|
-
React.createElement(Text, { color: "red" },
|
|
87
|
-
"Unknown command: ",
|
|
88
|
-
commandName),
|
|
89
|
-
React.createElement(Text, null,
|
|
90
|
-
"Run ",
|
|
91
|
-
React.createElement(Text, { bold: true }, "svc --help"),
|
|
92
|
-
" to see available commands")));
|
|
144
|
+
render(_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { color: "red", children: ["Unknown command: ", commandName] }), _jsxs(Text, { children: ["Run ", _jsx(Text, { bold: true, children: "svc --help" }), " to see available commands"] })] }));
|
|
93
145
|
process.exit(1);
|
|
94
146
|
}
|
|
95
147
|
// Offer to migrate a legacy plaintext password into the OS keychain.
|
|
@@ -115,7 +167,7 @@ async function main() {
|
|
|
115
167
|
args,
|
|
116
168
|
});
|
|
117
169
|
}
|
|
118
|
-
main().catch(
|
|
170
|
+
main().catch(error => {
|
|
119
171
|
console.error('Fatal error:', error);
|
|
120
172
|
process.exit(1);
|
|
121
173
|
});
|
package/dist/commands/build.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ interface BuildScreenProps {
|
|
|
7
7
|
createZip?: boolean;
|
|
8
8
|
onBack?: () => void;
|
|
9
9
|
}
|
|
10
|
-
export declare function BuildScreen({ projectRoot, manifest, createZip, onBack }: BuildScreenProps): React.JSX.Element;
|
|
10
|
+
export declare function BuildScreen({ projectRoot, manifest, createZip, onBack, }: BuildScreenProps): React.JSX.Element;
|
|
11
11
|
export declare const buildCommand: Command;
|
|
12
12
|
export {};
|
package/dist/commands/build.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, Box, Text, useInput } from 'ink';
|
|
3
4
|
import { StatusIndicator } from '../components/StatusIndicator.js';
|
|
4
5
|
import { WebpackRunner } from '../utils/webpack-runner.js';
|
|
5
6
|
import { copyStaticToBuild, copySrcToBuild, cleanBuild, formatFileSize, createBuildZip, getZipSize, } from '../utils/zip.js';
|
|
6
7
|
import { isBundledApp, getAppType, getFullAppId, } from '../utils/project-detection.js';
|
|
7
|
-
export function BuildScreen({ projectRoot, manifest, createZip = true, onBack }) {
|
|
8
|
+
export function BuildScreen({ projectRoot, manifest, createZip = true, onBack, }) {
|
|
8
9
|
const [state, setState] = React.useState({
|
|
9
10
|
status: 'cleaning',
|
|
10
11
|
message: 'Cleaning build directory...',
|
|
11
12
|
});
|
|
12
13
|
useInput((input, key) => {
|
|
13
|
-
if (onBack &&
|
|
14
|
+
if (onBack &&
|
|
15
|
+
(key.escape || input === 'q') &&
|
|
16
|
+
(state.status === 'success' || state.status === 'error')) {
|
|
14
17
|
onBack();
|
|
15
18
|
}
|
|
16
19
|
});
|
|
@@ -119,35 +122,8 @@ export function BuildScreen({ projectRoot, manifest, createZip = true, onBack })
|
|
|
119
122
|
return 'Build failed';
|
|
120
123
|
}
|
|
121
124
|
};
|
|
122
|
-
return (
|
|
123
|
-
|
|
124
|
-
React.createElement(StatusIndicator, { status: getStatusIndicator(), label: getStatusLabel(), message: state.message })),
|
|
125
|
-
state.status === 'success' && state.result?.stats && (React.createElement(Box, { flexDirection: "column", marginLeft: 2 },
|
|
126
|
-
React.createElement(Text, { dimColor: true },
|
|
127
|
-
"Compiled in ",
|
|
128
|
-
state.result.stats.time,
|
|
129
|
-
"ms"),
|
|
130
|
-
state.result.stats.assets && state.result.stats.assets.length > 0 && (React.createElement(Text, { dimColor: true },
|
|
131
|
-
"Assets: ",
|
|
132
|
-
state.result.stats.assets.join(', '))))),
|
|
133
|
-
state.status === 'success' && state.zipPath && (React.createElement(Box, { flexDirection: "column", marginLeft: 2, marginTop: 1 },
|
|
134
|
-
React.createElement(Text, { color: "green" },
|
|
135
|
-
"\u2713 Created: ",
|
|
136
|
-
state.zipPath),
|
|
137
|
-
state.zipSize !== undefined && (React.createElement(Text, { dimColor: true },
|
|
138
|
-
" Size: ",
|
|
139
|
-
formatFileSize(state.zipSize))))),
|
|
140
|
-
state.result?.warnings && state.result.warnings.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
141
|
-
React.createElement(Text, { color: "yellow" }, "Warnings:"),
|
|
142
|
-
state.result.warnings.slice(0, 5).map((warning, i) => (React.createElement(Text, { key: i, color: "yellow", dimColor: true }, warning.substring(0, 200)))),
|
|
143
|
-
state.result.warnings.length > 5 && (React.createElement(Text, { color: "yellow", dimColor: true },
|
|
144
|
-
"...and ",
|
|
145
|
-
state.result.warnings.length - 5,
|
|
146
|
-
" more")))),
|
|
147
|
-
state.status === 'error' && state.error && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
148
|
-
React.createElement(Text, { color: "red" }, state.error))),
|
|
149
|
-
onBack && (state.status === 'success' || state.status === 'error') && (React.createElement(Box, { marginTop: 1 },
|
|
150
|
-
React.createElement(Text, { dimColor: true }, "Press q or Esc to return to menu")))));
|
|
125
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(StatusIndicator, { status: getStatusIndicator(), label: getStatusLabel(), message: state.message }) }), state.status === 'success' && state.result?.stats && (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Text, { dimColor: true, children: ["Compiled in ", state.result.stats.time, "ms"] }), state.result.stats.assets &&
|
|
126
|
+
state.result.stats.assets.length > 0 && (_jsxs(Text, { dimColor: true, children: ["Assets: ", state.result.stats.assets.join(', ')] }))] })), state.status === 'success' && state.zipPath && (_jsxs(Box, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: [_jsxs(Text, { color: "green", children: ["\u2713 Created: ", state.zipPath] }), state.zipSize !== undefined && (_jsxs(Text, { dimColor: true, children: [" Size: ", formatFileSize(state.zipSize)] }))] })), state.result?.warnings && state.result.warnings.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "yellow", children: "Warnings:" }), state.result.warnings.slice(0, 5).map((warning, i) => (_jsx(Text, { color: "yellow", dimColor: true, children: warning.substring(0, 200) }, i))), state.result.warnings.length > 5 && (_jsxs(Text, { color: "yellow", dimColor: true, children: ["...and ", state.result.warnings.length - 5, " more"] }))] })), state.status === 'error' && state.error && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Text, { color: "red", children: state.error }) })), onBack && (state.status === 'success' || state.status === 'error') && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press q or Esc to return to menu" }) }))] }));
|
|
151
127
|
}
|
|
152
128
|
export const buildCommand = {
|
|
153
129
|
name: 'build',
|
|
@@ -162,7 +138,7 @@ export const buildCommand = {
|
|
|
162
138
|
},
|
|
163
139
|
async execute({ project, flags }) {
|
|
164
140
|
const createZip = !flags['no-zip'];
|
|
165
|
-
const { waitUntilExit } = render(
|
|
141
|
+
const { waitUntilExit } = render(_jsx(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: createZip }));
|
|
166
142
|
await waitUntilExit();
|
|
167
143
|
},
|
|
168
144
|
};
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, Box, Text, useInput } from 'ink';
|
|
3
4
|
import { StatusIndicator } from '../components/StatusIndicator.js';
|
|
@@ -99,24 +100,20 @@ export function DeployScreen({ projectRoot, manifest, devProperties, force, prod
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
runDeploy();
|
|
102
|
-
}, [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
React.createElement(Text, { color: "red" }, state.error))),
|
|
117
|
-
state.status !== 'deploying' && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
118
|
-
state.status === 'error' && onRetryCredentials && (React.createElement(Text, { dimColor: true }, "Press r to retry with new credentials")),
|
|
119
|
-
onBack && (React.createElement(Text, { dimColor: true }, "Press q or Esc to return to menu"))))));
|
|
103
|
+
}, [
|
|
104
|
+
projectRoot,
|
|
105
|
+
manifest,
|
|
106
|
+
devProperties,
|
|
107
|
+
force,
|
|
108
|
+
production,
|
|
109
|
+
activate,
|
|
110
|
+
signingPassword,
|
|
111
|
+
]);
|
|
112
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(StatusIndicator, { status: state.status === 'deploying' ? 'running' : state.status, label: state.status === 'deploying'
|
|
113
|
+
? 'Deploying'
|
|
114
|
+
: state.status === 'success'
|
|
115
|
+
? 'Deployed'
|
|
116
|
+
: 'Failed', message: state.message }) }), state.status === 'success' && (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Text, { color: "green", children: [production ? 'Production deployment' : 'Dev deployment', " complete"] }), state.executableId && (_jsxs(Text, { dimColor: true, children: ["Executable ID: ", state.executableId] })), force && _jsx(Text, { dimColor: true, children: "(Force mode - overwrote existing)" }), activate && production && _jsx(Text, { dimColor: true, children: "(Activated)" })] })), state.status === 'error' && state.error && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Text, { color: "red", children: state.error }) })), state.status !== 'deploying' && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [state.status === 'error' && onRetryCredentials && (_jsx(Text, { dimColor: true, children: "Press r to retry with new credentials" })), onBack && _jsx(Text, { dimColor: true, children: "Press q or Esc to return to menu" })] }))] }));
|
|
120
117
|
}
|
|
121
118
|
export const deployCommand = {
|
|
122
119
|
name: 'deploy',
|
|
@@ -169,11 +166,13 @@ export const deployCommand = {
|
|
|
169
166
|
const activate = Boolean(flags['activate']);
|
|
170
167
|
// For production, we need the signed zip, which requires signing credentials
|
|
171
168
|
let signingPassword;
|
|
172
|
-
if (production &&
|
|
169
|
+
if (production &&
|
|
170
|
+
project.hasSigningProperties &&
|
|
171
|
+
project.devProperties.signingUsername) {
|
|
173
172
|
// We already have a signed zip, no need to prompt for password here
|
|
174
173
|
// The sign command should have been run separately
|
|
175
174
|
}
|
|
176
|
-
const { waitUntilExit } = render(
|
|
175
|
+
const { waitUntilExit } = render(_jsx(DeployScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, force: force, production: production, activate: activate, signingPassword: signingPassword }));
|
|
177
176
|
await waitUntilExit();
|
|
178
177
|
},
|
|
179
178
|
};
|
package/dist/commands/dev.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, Box, Text, useApp, useInput } from 'ink';
|
|
3
4
|
import { StatusIndicator } from '../components/StatusIndicator.js';
|
|
4
5
|
import { WebpackRunner } from '../utils/webpack-runner.js';
|
|
5
6
|
import { promptPassword, promptYesNo } from '../utils/password-prompt.js';
|
|
6
7
|
import { signApp, deployApp } from '../utils/sitevision-api.js';
|
|
7
|
-
import { getSigningPassword, setSigningPassword, setDeployPassword } from '../utils/keychain.js';
|
|
8
|
-
import { copyStaticToBuild, createBuildZip, cleanBuild
|
|
8
|
+
import { getSigningPassword, setSigningPassword, setDeployPassword, } from '../utils/keychain.js';
|
|
9
|
+
import { copyStaticToBuild, createBuildZip, cleanBuild } from '../utils/zip.js';
|
|
9
10
|
import { isBundledApp, getAppType, getFullAppId, getZipPath, getSignedZipPath, } from '../utils/project-detection.js';
|
|
10
11
|
export function DevScreen({ projectRoot, manifest, devProperties, signed, signingCredentials, onBack, onRetryCredentials, }) {
|
|
11
12
|
const { exit } = useApp();
|
|
@@ -218,33 +219,9 @@ export function DevScreen({ projectRoot, manifest, devProperties, signed, signin
|
|
|
218
219
|
return 'Error';
|
|
219
220
|
}
|
|
220
221
|
};
|
|
221
|
-
return (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
state.buildCount > 0 && (React.createElement(Box, { marginLeft: 2, marginBottom: 1 },
|
|
225
|
-
React.createElement(Text, { dimColor: true },
|
|
226
|
-
"Builds: ",
|
|
227
|
-
state.buildCount,
|
|
228
|
-
state.lastBuildTime ? ` | Last build: ${state.lastBuildTime}ms` : '',
|
|
229
|
-
signed ? ' | Signed mode' : ''))),
|
|
230
|
-
React.createElement(Box, { marginLeft: 2, marginBottom: 1 },
|
|
231
|
-
React.createElement(Text, { dimColor: true },
|
|
232
|
-
manifest.name,
|
|
233
|
-
" v",
|
|
234
|
-
manifest.version)),
|
|
235
|
-
devProperties && (React.createElement(Box, { marginLeft: 2, marginBottom: 1 },
|
|
236
|
-
React.createElement(Text, { dimColor: true },
|
|
237
|
-
"Target: ",
|
|
238
|
-
devProperties.domain,
|
|
239
|
-
"/",
|
|
240
|
-
devProperties.siteName,
|
|
241
|
-
"/",
|
|
242
|
-
devProperties.addonName))),
|
|
243
|
-
state.status === 'error' && state.error && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
244
|
-
React.createElement(Text, { color: "red" }, state.error))),
|
|
245
|
-
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
246
|
-
state.status === 'error' && onRetryCredentials && (React.createElement(Text, { dimColor: true }, "Press r to retry with new credentials")),
|
|
247
|
-
onBack ? (React.createElement(Text, { dimColor: true }, "Press q or Esc to return to menu (Ctrl+C to stop process)")) : (React.createElement(Text, { dimColor: true }, "Press Ctrl+C to stop")))));
|
|
222
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(StatusIndicator, { status: getStatusType(), label: getStatusLabel(), message: state.message }) }), state.buildCount > 0 && (_jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: ["Builds: ", state.buildCount, state.lastBuildTime
|
|
223
|
+
? ` | Last build: ${state.lastBuildTime}ms`
|
|
224
|
+
: '', signed ? ' | Signed mode' : ''] }) })), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: [manifest.name, " v", manifest.version] }) }), devProperties && (_jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: ["Target: ", devProperties.domain, "/", devProperties.siteName, "/", devProperties.addonName] }) })), state.status === 'error' && state.error && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Text, { color: "red", children: state.error }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [state.status === 'error' && onRetryCredentials && (_jsx(Text, { dimColor: true, children: "Press r to retry with new credentials" })), onBack ? (_jsx(Text, { dimColor: true, children: "Press q or Esc to return to menu (Ctrl+C to stop process)" })) : (_jsx(Text, { dimColor: true, children: "Press Ctrl+C to stop" }))] })] }));
|
|
248
225
|
}
|
|
249
226
|
export const devCommand = {
|
|
250
227
|
name: 'dev',
|
|
@@ -284,13 +261,16 @@ export const devCommand = {
|
|
|
284
261
|
let signingCredentials;
|
|
285
262
|
// If signed mode, resolve signing password (keychain → env → prompt)
|
|
286
263
|
if (signed) {
|
|
287
|
-
if (!project.hasSigningProperties ||
|
|
264
|
+
if (!project.hasSigningProperties ||
|
|
265
|
+
!project.devProperties.signingUsername) {
|
|
288
266
|
console.log('\n\x1b[33mSigning credentials not configured.\x1b[0m');
|
|
289
267
|
console.log('Run \x1b[36msetup-signing\x1b[0m to configure credentials.\n');
|
|
290
268
|
return;
|
|
291
269
|
}
|
|
292
270
|
const signingUsername = project.devProperties.signingUsername;
|
|
293
|
-
let password = getSigningPassword(signingUsername) ||
|
|
271
|
+
let password = getSigningPassword(signingUsername) ||
|
|
272
|
+
process.env['SITEVISION_SIGNING_PASSWORD'] ||
|
|
273
|
+
'';
|
|
294
274
|
let promptedManually = false;
|
|
295
275
|
if (!password) {
|
|
296
276
|
console.log('');
|
|
@@ -313,7 +293,7 @@ export const devCommand = {
|
|
|
313
293
|
certificateName: project.devProperties.certificateName,
|
|
314
294
|
};
|
|
315
295
|
}
|
|
316
|
-
const { waitUntilExit } = render(
|
|
296
|
+
const { waitUntilExit } = render(_jsx(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, signed: signed, signingCredentials: signingCredentials }));
|
|
317
297
|
await waitUntilExit();
|
|
318
298
|
},
|
|
319
299
|
};
|
package/dist/commands/index.js
CHANGED
|
@@ -13,7 +13,7 @@ export const commands = [
|
|
|
13
13
|
setupSigningCommand,
|
|
14
14
|
];
|
|
15
15
|
export function getCommand(name) {
|
|
16
|
-
return commands.find(
|
|
16
|
+
return commands.find(cmd => cmd.name === name);
|
|
17
17
|
}
|
|
18
18
|
export function getAllCommands() {
|
|
19
19
|
return commands;
|
package/dist/commands/info.js
CHANGED
|
@@ -1,66 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { render } from 'ink';
|
|
3
3
|
import { Box, Text } from 'ink';
|
|
4
4
|
import { getAppType } from '../utils/project-detection.js';
|
|
5
5
|
function InfoScreen({ project }) {
|
|
6
6
|
const appType = getAppType(project.manifest);
|
|
7
|
-
return (
|
|
8
|
-
React.createElement(Box, { marginBottom: 1 },
|
|
9
|
-
React.createElement(Text, { bold: true, color: "cyan" }, "Sitevision Project Information")),
|
|
10
|
-
React.createElement(Box, { flexDirection: "column", marginLeft: 2 },
|
|
11
|
-
React.createElement(Box, null,
|
|
12
|
-
React.createElement(Text, { bold: true }, "Name: "),
|
|
13
|
-
React.createElement(Text, null, project.manifest.name)),
|
|
14
|
-
React.createElement(Box, null,
|
|
15
|
-
React.createElement(Text, { bold: true }, "ID: "),
|
|
16
|
-
React.createElement(Text, null, project.manifest.id)),
|
|
17
|
-
React.createElement(Box, null,
|
|
18
|
-
React.createElement(Text, { bold: true }, "Version: "),
|
|
19
|
-
React.createElement(Text, null, project.manifest.version)),
|
|
20
|
-
React.createElement(Box, null,
|
|
21
|
-
React.createElement(Text, { bold: true }, "Type: "),
|
|
22
|
-
React.createElement(Text, { color: "green" }, project.manifest.type),
|
|
23
|
-
React.createElement(Text, { dimColor: true },
|
|
24
|
-
" (",
|
|
25
|
-
appType,
|
|
26
|
-
")")),
|
|
27
|
-
React.createElement(Box, null,
|
|
28
|
-
React.createElement(Text, { bold: true }, "Bundled: "),
|
|
29
|
-
React.createElement(Text, null, project.manifest.bundled ? 'Yes' : 'No'))),
|
|
30
|
-
project.hasDevProperties && project.devProperties && (React.createElement(React.Fragment, null,
|
|
31
|
-
React.createElement(Box, { marginTop: 1, marginBottom: 1 },
|
|
32
|
-
React.createElement(Text, { bold: true, color: "cyan" }, "Development Configuration")),
|
|
33
|
-
React.createElement(Box, { flexDirection: "column", marginLeft: 2 },
|
|
34
|
-
React.createElement(Box, null,
|
|
35
|
-
React.createElement(Text, { bold: true }, "Domain: "),
|
|
36
|
-
React.createElement(Text, null, project.devProperties.domain)),
|
|
37
|
-
React.createElement(Box, null,
|
|
38
|
-
React.createElement(Text, { bold: true }, "Site: "),
|
|
39
|
-
React.createElement(Text, null, project.devProperties.siteName)),
|
|
40
|
-
React.createElement(Box, null,
|
|
41
|
-
React.createElement(Text, { bold: true }, "Addon: "),
|
|
42
|
-
React.createElement(Text, null, project.devProperties.addonName)),
|
|
43
|
-
React.createElement(Box, null,
|
|
44
|
-
React.createElement(Text, { bold: true }, "Username: "),
|
|
45
|
-
React.createElement(Text, null, project.devProperties.username)),
|
|
46
|
-
React.createElement(Box, null,
|
|
47
|
-
React.createElement(Text, { bold: true }, "Use HTTP: "),
|
|
48
|
-
React.createElement(Text, null, project.devProperties.useHTTPForDevDeploy ? 'Yes' : 'No'))))),
|
|
49
|
-
!project.hasDevProperties && (React.createElement(Box, { marginTop: 1 },
|
|
50
|
-
React.createElement(Text, { color: "yellow" },
|
|
51
|
-
"\u26A0 No dev properties found. Run",
|
|
52
|
-
' ',
|
|
53
|
-
React.createElement(Text, { bold: true }, "setup-dev-properties"),
|
|
54
|
-
" to configure."))),
|
|
55
|
-
React.createElement(Box, { marginTop: 1 },
|
|
56
|
-
React.createElement(Text, { bold: true }, "Project Root: "),
|
|
57
|
-
React.createElement(Text, { dimColor: true }, project.root))));
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision Project Information" }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Name: " }), _jsx(Text, { children: project.manifest.name })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "ID: " }), _jsx(Text, { children: project.manifest.id })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Version: " }), _jsx(Text, { children: project.manifest.version })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Type: " }), _jsx(Text, { color: "green", children: project.manifest.type }), _jsxs(Text, { dimColor: true, children: [" (", appType, ")"] })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Bundled: " }), _jsx(Text, { children: project.manifest.bundled ? 'Yes' : 'No' })] })] }), project.hasDevProperties && project.devProperties && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Development Configuration" }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Domain: " }), _jsx(Text, { children: project.devProperties.domain })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Site: " }), _jsx(Text, { children: project.devProperties.siteName })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Addon: " }), _jsx(Text, { children: project.devProperties.addonName })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Username: " }), _jsx(Text, { children: project.devProperties.username })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Use HTTP: " }), _jsx(Text, { children: project.devProperties.useHTTPForDevDeploy ? 'Yes' : 'No' })] })] })] })), !project.hasDevProperties && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["\u26A0 No dev properties found. Run", ' ', _jsx(Text, { bold: true, children: "setup-dev-properties" }), " to configure."] }) })), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { bold: true, children: "Project Root: " }), _jsx(Text, { dimColor: true, children: project.root })] })] }));
|
|
58
8
|
}
|
|
59
9
|
export const infoCommand = {
|
|
60
10
|
name: 'info',
|
|
61
11
|
description: 'Show project information',
|
|
62
12
|
requiresProject: true,
|
|
63
13
|
async execute({ project }) {
|
|
64
|
-
render(
|
|
14
|
+
render(_jsx(InfoScreen, { project: project }));
|
|
65
15
|
},
|
|
66
16
|
};
|
|
@@ -2,8 +2,8 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import readline from 'readline';
|
|
4
4
|
function question(rl, prompt) {
|
|
5
|
-
return new Promise(
|
|
6
|
-
rl.question(prompt,
|
|
5
|
+
return new Promise(resolve => {
|
|
6
|
+
rl.question(prompt, answer => {
|
|
7
7
|
resolve(answer);
|
|
8
8
|
});
|
|
9
9
|
});
|
package/dist/commands/sign.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ interface SignScreenProps {
|
|
|
9
9
|
onBack?: () => void;
|
|
10
10
|
onRetryCredentials?: () => void;
|
|
11
11
|
}
|
|
12
|
-
export declare function SignScreen({ projectRoot, manifest, devProperties, password, onBack, onRetryCredentials }: SignScreenProps): React.JSX.Element;
|
|
12
|
+
export declare function SignScreen({ projectRoot, manifest, devProperties, password, onBack, onRetryCredentials, }: SignScreenProps): React.JSX.Element;
|
|
13
13
|
export declare const signCommand: Command;
|
|
14
14
|
export {};
|