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.
Files changed (48) hide show
  1. package/dist/app.d.ts +1 -2
  2. package/dist/app.js +19 -14
  3. package/dist/cli.js +76 -24
  4. package/dist/commands/build.d.ts +1 -1
  5. package/dist/commands/build.js +8 -32
  6. package/dist/commands/deploy.js +19 -20
  7. package/dist/commands/dev.js +12 -32
  8. package/dist/commands/index.js +1 -1
  9. package/dist/commands/info.js +3 -53
  10. package/dist/commands/setup-signing.js +2 -2
  11. package/dist/commands/sign.d.ts +1 -1
  12. package/dist/commands/sign.js +14 -20
  13. package/dist/components/DevPropertiesForm.d.ts +1 -2
  14. package/dist/components/DevPropertiesForm.js +15 -30
  15. package/dist/components/InfoScreen.d.ts +1 -2
  16. package/dist/components/InfoScreen.js +2 -50
  17. package/dist/components/MainMenu.d.ts +1 -2
  18. package/dist/components/MainMenu.js +5 -70
  19. package/dist/components/PasswordInput.d.ts +1 -2
  20. package/dist/components/PasswordInput.js +7 -19
  21. package/dist/components/ProcessOutput.d.ts +1 -2
  22. package/dist/components/ProcessOutput.js +3 -5
  23. package/dist/components/SetupFlow.d.ts +1 -2
  24. package/dist/components/SetupFlow.js +12 -87
  25. package/dist/components/SigningPropertiesForm.d.ts +1 -2
  26. package/dist/components/SigningPropertiesForm.js +7 -18
  27. package/dist/components/StatusIndicator.d.ts +1 -2
  28. package/dist/components/StatusIndicator.js +6 -12
  29. package/dist/components/TextInput.d.ts +1 -2
  30. package/dist/components/TextInput.js +5 -13
  31. package/dist/components/WelcomeScreen.d.ts +14 -0
  32. package/dist/components/WelcomeScreen.js +53 -0
  33. package/dist/utils/branding.d.ts +12 -0
  34. package/dist/utils/branding.js +29 -0
  35. package/dist/utils/config.d.ts +17 -0
  36. package/dist/utils/config.js +57 -0
  37. package/dist/utils/password-prompt.js +2 -2
  38. package/dist/utils/process-runner.d.ts +6 -6
  39. package/dist/utils/process-runner.js +12 -42
  40. package/dist/utils/project-detection.d.ts +1 -1
  41. package/dist/utils/project-detection.js +7 -3
  42. package/dist/utils/sitevision-api.js +1 -1
  43. package/dist/utils/version-check.js +3 -3
  44. package/dist/utils/webpack-runner.d.ts +2 -2
  45. package/dist/utils/webpack-runner.js +15 -42
  46. package/dist/utils/zip.js +5 -7
  47. package/package.json +23 -30
  48. 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): React.JSX.Element | null;
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 React, { useState } from 'react';
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 && project.devProperties?.domain && project.devProperties.username && password) {
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 React.createElement(SetupFlow, { project: project, onComplete: () => setState('menu') });
138
+ return _jsx(SetupFlow, { project: project, onComplete: () => setState('menu') });
135
139
  }
136
140
  if (state === 'menu') {
137
- return React.createElement(MainMenu, { project: project, onSelect: handleCommandSelect });
141
+ return _jsx(MainMenu, { project: project, onSelect: handleCommandSelect });
138
142
  }
139
143
  if (state === 'info') {
140
- return React.createElement(InfoScreen, { project: project, onBack: () => setState('menu') });
144
+ return _jsx(InfoScreen, { project: project, onBack: () => setState('menu') });
141
145
  }
142
146
  if (state === 'dev-password-input') {
143
- return (React.createElement(PasswordInput, { key: "dev-password", label: "Enter Development Password (usually Sitevision Cloud Password)", showRememberOption: Boolean(project.devProperties?.domain && project.devProperties?.username), onSubmit: handleDevPasswordSubmit, onCancel: () => setState('menu') }));
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 (React.createElement(PasswordInput, { key: "signing-password", label: "Enter Signing Password (developer.sitevision.se)", showRememberOption: Boolean(project.devProperties?.signingUsername), onSubmit: handleSigningPasswordSubmit, onCancel: () => setState('menu') }));
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 (React.createElement(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: getEffectiveDevProperties(), signed: currentCommand === 'dev-signed', onBack: () => setState('menu'), onRetryCredentials: () => {
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' && project.devProperties?.signingUsername
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 (React.createElement(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: true, onBack: () => setState('menu') }));
171
+ return (_jsx(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: true, onBack: () => setState('menu') }));
167
172
  }
168
173
  if (state === 'sign') {
169
- return (React.createElement(SignScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, password: signingPassword, onBack: () => setState('menu'), onRetryCredentials: () => {
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 (React.createElement(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: () => {
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 (React.createElement(SigningPropertiesForm, { projectRoot: project.root, onComplete: () => {
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 React from 'react';
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
- alias: 'f',
48
+ shortFlag: 'f',
46
49
  default: false,
47
50
  },
48
51
  production: {
49
52
  type: 'boolean',
50
- alias: 'p',
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
- // Show the CLI version on startup, and check npm for a newer release.
58
- console.log(`\x1b[36msvc v${pkg.version}\x1b[0m`);
59
- const latestVersion = await checkForUpdate(pkg.name, pkg.version);
60
- if (latestVersion) {
61
- console.log(`\x1b[33m ↑ update available: ${pkg.version} ${latestVersion} (run: npm i -g ${pkg.name})\x1b[0m`);
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(React.createElement(Box, { flexDirection: "column", padding: 1 },
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(React.createElement(App, { project: project }));
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(React.createElement(Box, { flexDirection: "column", padding: 1 },
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((error) => {
170
+ main().catch(error => {
119
171
  console.error('Fatal error:', error);
120
172
  process.exit(1);
121
173
  });
@@ -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 {};
@@ -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 && (key.escape || input === 'q') && (state.status === 'success' || state.status === 'error')) {
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 (React.createElement(Box, { flexDirection: "column", padding: 1 },
123
- React.createElement(Box, { marginBottom: 1 },
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(React.createElement(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: createZip }));
141
+ const { waitUntilExit } = render(_jsx(BuildScreen, { projectRoot: project.root, manifest: project.manifest, createZip: createZip }));
166
142
  await waitUntilExit();
167
143
  },
168
144
  };
@@ -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
- }, [projectRoot, manifest, devProperties, force, production, activate, signingPassword]);
103
- return (React.createElement(Box, { flexDirection: "column", padding: 1 },
104
- React.createElement(Box, { marginBottom: 1 },
105
- React.createElement(StatusIndicator, { status: state.status === 'deploying' ? 'running' : state.status, label: state.status === 'deploying' ? 'Deploying' : state.status === 'success' ? 'Deployed' : 'Failed', message: state.message })),
106
- state.status === 'success' && (React.createElement(Box, { flexDirection: "column", marginLeft: 2 },
107
- React.createElement(Text, { color: "green" },
108
- production ? 'Production deployment' : 'Dev deployment',
109
- " complete"),
110
- state.executableId && (React.createElement(Text, { dimColor: true },
111
- "Executable ID: ",
112
- state.executableId)),
113
- force && React.createElement(Text, { dimColor: true }, "(Force mode - overwrote existing)"),
114
- activate && production && React.createElement(Text, { dimColor: true }, "(Activated)"))),
115
- state.status === 'error' && state.error && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
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 && project.hasSigningProperties && project.devProperties.signingUsername) {
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(React.createElement(DeployScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, force: force, production: production, activate: activate, signingPassword: signingPassword }));
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
  };
@@ -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, } from '../utils/zip.js';
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 (React.createElement(Box, { flexDirection: "column", padding: 1 },
222
- React.createElement(Box, { marginBottom: 1 },
223
- React.createElement(StatusIndicator, { status: getStatusType(), label: getStatusLabel(), message: state.message })),
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 || !project.devProperties.signingUsername) {
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) || process.env['SITEVISION_SIGNING_PASSWORD'] || '';
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(React.createElement(DevScreen, { projectRoot: project.root, manifest: project.manifest, devProperties: project.devProperties, signed: signed, signingCredentials: signingCredentials }));
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
  };
@@ -13,7 +13,7 @@ export const commands = [
13
13
  setupSigningCommand,
14
14
  ];
15
15
  export function getCommand(name) {
16
- return commands.find((cmd) => cmd.name === name);
16
+ return commands.find(cmd => cmd.name === name);
17
17
  }
18
18
  export function getAllCommands() {
19
19
  return commands;
@@ -1,66 +1,16 @@
1
- import React from 'react';
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 (React.createElement(Box, { flexDirection: "column", padding: 1 },
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(React.createElement(InfoScreen, { project: project }));
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((resolve) => {
6
- rl.question(prompt, (answer) => {
5
+ return new Promise(resolve => {
6
+ rl.question(prompt, answer => {
7
7
  resolve(answer);
8
8
  });
9
9
  });
@@ -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 {};