sitevision-cli 0.6.0-beta.2 → 1.0.0-beta.1
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.js +44 -8
- package/dist/cli.js +4 -0
- package/dist/commands/dev.d.ts +3 -2
- package/dist/commands/dev.js +17 -3
- package/dist/commands/index.js +2 -0
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.js +44 -0
- package/dist/components/DevPropertiesForm.js +1 -1
- package/dist/components/MainMenu.js +10 -0
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -24,6 +24,15 @@ export default function App({ project }) {
|
|
|
24
24
|
// slow and this component re-renders frequently).
|
|
25
25
|
const signingUsername = project.devProperties?.signingUsername;
|
|
26
26
|
const storedSigningPassword = useMemo(() => (signingUsername ? getSigningPassword(signingUsername) : null), [signingUsername]);
|
|
27
|
+
// Map a signing-capable command to the screen it lands on once the signing
|
|
28
|
+
// password is resolved.
|
|
29
|
+
const signedDestination = (command = currentCommand) => {
|
|
30
|
+
if (command === 'dev-signed')
|
|
31
|
+
return 'dev';
|
|
32
|
+
if (command === 'watch-signed')
|
|
33
|
+
return 'watch';
|
|
34
|
+
return 'sign';
|
|
35
|
+
};
|
|
27
36
|
// Decide the next step once a signing password is needed: proceed if we already
|
|
28
37
|
// have one this session, offer the keychain choice if one is saved, otherwise
|
|
29
38
|
// prompt for manual entry.
|
|
@@ -34,7 +43,7 @@ export default function App({ project }) {
|
|
|
34
43
|
isRetry: signingRetry,
|
|
35
44
|
});
|
|
36
45
|
if (step === 'proceed') {
|
|
37
|
-
setState(command
|
|
46
|
+
setState(signedDestination(command));
|
|
38
47
|
}
|
|
39
48
|
else if (step === 'choice') {
|
|
40
49
|
setState('signing-password-choice');
|
|
@@ -78,7 +87,7 @@ export default function App({ project }) {
|
|
|
78
87
|
if (storedSigningPassword) {
|
|
79
88
|
setSigningPassword(storedSigningPassword);
|
|
80
89
|
}
|
|
81
|
-
setState(
|
|
90
|
+
setState(signedDestination());
|
|
82
91
|
};
|
|
83
92
|
const handleEnterNewSigning = () => {
|
|
84
93
|
setState('signing-password-input');
|
|
@@ -88,12 +97,7 @@ export default function App({ project }) {
|
|
|
88
97
|
if (remember && project.devProperties?.signingUsername && password) {
|
|
89
98
|
saveSigningPassword(project.devProperties.signingUsername, password);
|
|
90
99
|
}
|
|
91
|
-
|
|
92
|
-
setState('dev');
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
setState('sign');
|
|
96
|
-
}
|
|
100
|
+
setState(signedDestination());
|
|
97
101
|
};
|
|
98
102
|
const handleCommandSelect = (command) => {
|
|
99
103
|
setCurrentCommand(command);
|
|
@@ -135,6 +139,21 @@ export default function App({ project }) {
|
|
|
135
139
|
routeToSigningStep(command);
|
|
136
140
|
}
|
|
137
141
|
break;
|
|
142
|
+
case 'watch':
|
|
143
|
+
// Build/sign-only: no deploy and no signing, so no credentials needed.
|
|
144
|
+
setState('watch');
|
|
145
|
+
break;
|
|
146
|
+
case 'watch-signed':
|
|
147
|
+
if (!project.hasDevProperties || !project.devProperties) {
|
|
148
|
+
console.log('\x1b[31mDevelopment properties not configured. Create a .dev_properties.json file first.\x1b[0m');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!project.hasSigningProperties) {
|
|
152
|
+
console.log('\x1b[31mSigning credentials not configured. Run svc setup-signing first.\x1b[0m');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
routeToSigningStep(command);
|
|
156
|
+
break;
|
|
138
157
|
case 'sign':
|
|
139
158
|
if (!project.hasDevProperties || !project.devProperties) {
|
|
140
159
|
console.log('\x1b[31mDevelopment properties not configured. Create a .dev_properties.json file first.\x1b[0m');
|
|
@@ -205,6 +224,23 @@ export default function App({ project }) {
|
|
|
205
224
|
}
|
|
206
225
|
: undefined }));
|
|
207
226
|
}
|
|
227
|
+
if (state === 'watch') {
|
|
228
|
+
const watchSigned = currentCommand === 'watch-signed';
|
|
229
|
+
return (_jsx(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, signed: watchSigned, deploy: false, onBack: () => setState('menu'), onRetryCredentials: watchSigned
|
|
230
|
+
? () => {
|
|
231
|
+
setSigningPassword('');
|
|
232
|
+
// The saved password may be what failed — don't re-offer it.
|
|
233
|
+
setSigningRetry(true);
|
|
234
|
+
routeToSigningStep('watch-signed');
|
|
235
|
+
}
|
|
236
|
+
: undefined, signingCredentials: watchSigned && project.devProperties?.signingUsername
|
|
237
|
+
? {
|
|
238
|
+
username: project.devProperties.signingUsername,
|
|
239
|
+
password: signingPassword,
|
|
240
|
+
certificateName: project.devProperties.certificateName,
|
|
241
|
+
}
|
|
242
|
+
: undefined }));
|
|
243
|
+
}
|
|
208
244
|
if (state === 'build') {
|
|
209
245
|
return (_jsx(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: true, onBack: () => setState('menu') }));
|
|
210
246
|
}
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,9 @@ const cli = meow(`
|
|
|
21
21
|
|
|
22
22
|
Commands
|
|
23
23
|
dev Start development server with watch mode
|
|
24
|
+
watch Watch and rebuild (optionally signing) without deploying
|
|
24
25
|
build Build the application for production
|
|
26
|
+
sign Sign the app for production deployment
|
|
25
27
|
deploy Deploy the application
|
|
26
28
|
info Show project information
|
|
27
29
|
|
|
@@ -33,6 +35,8 @@ const cli = meow(`
|
|
|
33
35
|
$ svc # Interactive menu
|
|
34
36
|
$ svc dev
|
|
35
37
|
$ svc dev --signed
|
|
38
|
+
$ svc watch
|
|
39
|
+
$ svc watch --signed
|
|
36
40
|
$ svc build
|
|
37
41
|
$ svc deploy --force
|
|
38
42
|
$ svc deploy --production
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -4,12 +4,13 @@ import type { SitevisionManifest, DevProperties, SigningCredentials } from '../t
|
|
|
4
4
|
interface DevScreenProps {
|
|
5
5
|
projectRoot: string;
|
|
6
6
|
manifest: SitevisionManifest;
|
|
7
|
-
devProperties
|
|
7
|
+
devProperties?: DevProperties;
|
|
8
8
|
signed: boolean;
|
|
9
|
+
deploy?: boolean;
|
|
9
10
|
signingCredentials?: SigningCredentials;
|
|
10
11
|
onBack?: () => void;
|
|
11
12
|
onRetryCredentials?: () => void;
|
|
12
13
|
}
|
|
13
|
-
export declare function DevScreen({ projectRoot, manifest, devProperties, signed, signingCredentials, onBack, onRetryCredentials, }: DevScreenProps): React.JSX.Element;
|
|
14
|
+
export declare function DevScreen({ projectRoot, manifest, devProperties, signed, deploy, signingCredentials, onBack, onRetryCredentials, }: DevScreenProps): React.JSX.Element;
|
|
14
15
|
export declare const devCommand: Command;
|
|
15
16
|
export {};
|
package/dist/commands/dev.js
CHANGED
|
@@ -12,7 +12,7 @@ import { setDeployPassword } from '../utils/keychain.js';
|
|
|
12
12
|
import { resolveSigningPassword } from '../utils/signing-password.js';
|
|
13
13
|
import { copyStaticToBuild, createBuildZip, cleanBuild } from '../utils/zip.js';
|
|
14
14
|
import { isBundledApp, getAppType, getFullAppId, getZipPath, getSignedZipPath, } from '../utils/project-detection.js';
|
|
15
|
-
export function DevScreen({ projectRoot, manifest, devProperties, signed, signingCredentials, onBack, onRetryCredentials, }) {
|
|
15
|
+
export function DevScreen({ projectRoot, manifest, devProperties, signed, deploy = true, signingCredentials, onBack, onRetryCredentials, }) {
|
|
16
16
|
const { exit } = useApp();
|
|
17
17
|
const [state, setState] = React.useState({
|
|
18
18
|
status: 'initializing',
|
|
@@ -57,6 +57,20 @@ export function DevScreen({ projectRoot, manifest, devProperties, signed, signin
|
|
|
57
57
|
}
|
|
58
58
|
deployZipPath = signedZipPath;
|
|
59
59
|
}
|
|
60
|
+
// Watch/build-only mode: stop after building (and signing).
|
|
61
|
+
if (!deploy || !devProperties) {
|
|
62
|
+
setState(prev => ({
|
|
63
|
+
...prev,
|
|
64
|
+
status: 'ready',
|
|
65
|
+
message: signed
|
|
66
|
+
? 'Signed. Watching for changes...'
|
|
67
|
+
: 'Built. Watching for changes...',
|
|
68
|
+
buildCount: prev.buildCount + 1,
|
|
69
|
+
lastBuildTime: buildTime,
|
|
70
|
+
error: undefined,
|
|
71
|
+
}));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
60
74
|
// Deploy
|
|
61
75
|
setState(prev => ({
|
|
62
76
|
...prev,
|
|
@@ -99,7 +113,7 @@ export function DevScreen({ projectRoot, manifest, devProperties, signed, signin
|
|
|
99
113
|
error: error instanceof Error ? error.message : String(error),
|
|
100
114
|
}));
|
|
101
115
|
}
|
|
102
|
-
}, [projectRoot, manifest, devProperties, signed, signingCredentials]);
|
|
116
|
+
}, [projectRoot, manifest, devProperties, signed, deploy, signingCredentials]);
|
|
103
117
|
// In-house webpack path: copy static, zip, then sign + deploy.
|
|
104
118
|
const handleBuildComplete = React.useCallback(async (result) => {
|
|
105
119
|
if (!result.success) {
|
|
@@ -339,7 +353,7 @@ export function DevScreen({ projectRoot, manifest, devProperties, signed, signin
|
|
|
339
353
|
};
|
|
340
354
|
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(StatusIndicator, { status: getStatusType(), label: getStatusLabel(), message: state.message }) }), state.warning && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "yellow", children: ["\u26A0 ", state.warning] }) })), state.buildCount > 0 && (_jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: ["Builds: ", state.buildCount, state.lastBuildTime
|
|
341
355
|
? ` | Last build: ${state.lastBuildTime}ms`
|
|
342
|
-
: '', 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" }))] })] }));
|
|
356
|
+
: '', signed ? ' | Signed mode' : ''] }) })), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: [manifest.name, " v", manifest.version] }) }), deploy && 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" }))] })] }));
|
|
343
357
|
}
|
|
344
358
|
export const devCommand = {
|
|
345
359
|
name: 'dev',
|
package/dist/commands/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { devCommand } from './dev.js';
|
|
2
|
+
import { watchCommand } from './watch.js';
|
|
2
3
|
import { buildCommand } from './build.js';
|
|
3
4
|
import { deployCommand } from './deploy.js';
|
|
4
5
|
import { infoCommand } from './info.js';
|
|
@@ -6,6 +7,7 @@ import { setupSigningCommand } from './setup-signing.js';
|
|
|
6
7
|
import { signCommand } from './sign.js';
|
|
7
8
|
export const commands = [
|
|
8
9
|
devCommand,
|
|
10
|
+
watchCommand,
|
|
9
11
|
buildCommand,
|
|
10
12
|
signCommand,
|
|
11
13
|
deployCommand,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render } from 'ink';
|
|
3
|
+
import { DevScreen } from './dev.js';
|
|
4
|
+
import { resolveSigningPassword } from '../utils/signing-password.js';
|
|
5
|
+
export const watchCommand = {
|
|
6
|
+
name: 'watch',
|
|
7
|
+
description: 'Watch and rebuild (optionally signing) without deploying',
|
|
8
|
+
requiresProject: true,
|
|
9
|
+
flags: {
|
|
10
|
+
signed: {
|
|
11
|
+
type: 'boolean',
|
|
12
|
+
description: 'Sign after each build',
|
|
13
|
+
alias: 's',
|
|
14
|
+
default: false,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
async execute({ project, flags }) {
|
|
18
|
+
const signed = Boolean(flags['signed']);
|
|
19
|
+
let signingCredentials;
|
|
20
|
+
// Signed mode: resolve signing credentials (keychain → env → prompt).
|
|
21
|
+
// No deploy credentials are needed — watch never deploys.
|
|
22
|
+
if (signed) {
|
|
23
|
+
if (!project.hasSigningProperties ||
|
|
24
|
+
!project.devProperties?.signingUsername) {
|
|
25
|
+
console.log('\n\x1b[33mSigning credentials not configured.\x1b[0m');
|
|
26
|
+
console.log('Run \x1b[36msetup-signing\x1b[0m to configure credentials.\n');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const signingUsername = project.devProperties.signingUsername;
|
|
30
|
+
const password = await resolveSigningPassword(signingUsername);
|
|
31
|
+
if (!password) {
|
|
32
|
+
console.log('\x1b[31mError: Password is required for signed mode\x1b[0m');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
signingCredentials = {
|
|
36
|
+
username: signingUsername,
|
|
37
|
+
password,
|
|
38
|
+
certificateName: project.devProperties.certificateName,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const { waitUntilExit } = render(_jsx(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, signed: signed, deploy: false, signingCredentials: signingCredentials }));
|
|
42
|
+
await waitUntilExit();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
@@ -56,7 +56,7 @@ export function DevPropertiesForm({ projectRoot, initialProperties, packageJson,
|
|
|
56
56
|
case 'password':
|
|
57
57
|
return (_jsx(TextInput, { label: "Password (saved in OS keychain \u2014 leave empty to prompt on each run)", type: "password", defaultValue: properties.password, onSubmit: (value) => handleNext('password', value), onCancel: onCancel }, "password"));
|
|
58
58
|
case 'useHTTP':
|
|
59
|
-
return (_jsx(BooleanInput, { label: "Use HTTP for deployment? (y/n)", defaultValue: properties.useHTTPForDevDeploy, onSubmit: (value) => handleNext('useHTTPForDevDeploy', value) }, "useHTTP"));
|
|
59
|
+
return (_jsx(BooleanInput, { label: "Use HTTP for deployment? (y/n)", defaultValue: properties.useHTTPForDevDeploy ?? false, onSubmit: (value) => handleNext('useHTTPForDevDeploy', value) }, "useHTTP"));
|
|
60
60
|
default:
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
@@ -16,6 +16,16 @@ export function MainMenu({ project, onSelect }) {
|
|
|
16
16
|
value: 'dev-signed',
|
|
17
17
|
description: 'Development with automatic signing',
|
|
18
18
|
},
|
|
19
|
+
{
|
|
20
|
+
label: '👀 Watch',
|
|
21
|
+
value: 'watch',
|
|
22
|
+
description: 'Rebuild on change without deploying',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: '👀 Watch (Signed)',
|
|
26
|
+
value: 'watch-signed',
|
|
27
|
+
description: 'Rebuild and sign on change without deploying',
|
|
28
|
+
},
|
|
19
29
|
{
|
|
20
30
|
label: '🔨 Build',
|
|
21
31
|
value: 'build',
|