sitevision-cli 1.0.0-beta.9 → 1.0.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/LICENSE +21 -0
  3. package/dist/cli.js +194 -70
  4. package/dist/commands/TaskScreen.js +32 -0
  5. package/dist/commands/build.js +6 -185
  6. package/dist/commands/deploy.js +95 -212
  7. package/dist/commands/dev.js +87 -416
  8. package/dist/commands/info.js +1 -1
  9. package/dist/commands/setup-signing.js +50 -33
  10. package/dist/commands/sign.js +9 -86
  11. package/dist/commands/use-finish.js +17 -0
  12. package/dist/commands/watch.js +5 -31
  13. package/dist/components/AnimatedLogo.js +8 -2
  14. package/dist/components/AuthLoginScreen.js +33 -15
  15. package/dist/components/PasswordInput.js +2 -1
  16. package/dist/scaffold/inquirer-stub.js +119 -0
  17. package/dist/scaffold/register.js +15 -0
  18. package/dist/shell/AddonPicker.js +54 -0
  19. package/dist/shell/Changelog.js +50 -0
  20. package/dist/shell/CommandPalette.js +63 -0
  21. package/dist/shell/ConfigForm.js +703 -0
  22. package/dist/shell/Frame.js +138 -0
  23. package/dist/shell/Help.js +96 -0
  24. package/dist/shell/Popover.js +15 -0
  25. package/dist/shell/Settings.js +149 -0
  26. package/dist/shell/Shell.js +953 -0
  27. package/dist/shell/Tabs.js +96 -0
  28. package/dist/shell/actions.js +493 -0
  29. package/dist/utils/config.js +62 -2
  30. package/dist/utils/create-app.js +231 -0
  31. package/dist/utils/debug.js +32 -0
  32. package/dist/utils/environments.js +74 -0
  33. package/dist/utils/i18n.js +369 -0
  34. package/dist/utils/jsonc.js +2 -1
  35. package/dist/utils/keychain.js +54 -6
  36. package/dist/utils/oauth2-auth.js +146 -43
  37. package/dist/utils/password-prompt.js +37 -3
  38. package/dist/utils/process-runner.js +77 -38
  39. package/dist/utils/project-detection.js +457 -112
  40. package/dist/utils/session-cookie-auth.js +10 -6
  41. package/dist/utils/sitevision-api.js +134 -25
  42. package/dist/utils/sitevision-scripts-runner.js +50 -22
  43. package/dist/utils/tasks.js +510 -0
  44. package/dist/utils/version-check.js +3 -3
  45. package/dist/utils/webpack-runner.js +9 -5
  46. package/dist/utils/workspace.js +105 -0
  47. package/dist/utils/zip.js +18 -19
  48. package/package.json +29 -5
  49. package/readme.md +117 -141
  50. package/dist/app.d.ts +0 -6
  51. package/dist/app.js +0 -307
  52. package/dist/cli.d.ts +0 -2
  53. package/dist/commands/build.d.ts +0 -12
  54. package/dist/commands/deploy.d.ts +0 -16
  55. package/dist/commands/dev.d.ts +0 -16
  56. package/dist/commands/index.d.ts +0 -4
  57. package/dist/commands/info.d.ts +0 -2
  58. package/dist/commands/setup-signing.d.ts +0 -2
  59. package/dist/commands/sign.d.ts +0 -14
  60. package/dist/commands/types.d.ts +0 -18
  61. package/dist/commands/watch.d.ts +0 -2
  62. package/dist/components/AnimatedLogo.d.ts +0 -10
  63. package/dist/components/AuthLoginScreen.d.ts +0 -21
  64. package/dist/components/DevPropertiesForm.d.ts +0 -10
  65. package/dist/components/DevPropertiesForm.js +0 -210
  66. package/dist/components/InfoScreen.d.ts +0 -7
  67. package/dist/components/InfoScreen.js +0 -14
  68. package/dist/components/KeychainPasswordChoice.d.ts +0 -8
  69. package/dist/components/KeychainPasswordChoice.js +0 -30
  70. package/dist/components/MainMenu.d.ts +0 -7
  71. package/dist/components/MainMenu.js +0 -83
  72. package/dist/components/PasswordInput.d.ts +0 -10
  73. package/dist/components/ProcessOutput.d.ts +0 -6
  74. package/dist/components/ProcessOutput.js +0 -30
  75. package/dist/components/SetupFlow.d.ts +0 -8
  76. package/dist/components/SetupFlow.js +0 -233
  77. package/dist/components/SigningPropertiesForm.d.ts +0 -7
  78. package/dist/components/SigningPropertiesForm.js +0 -38
  79. package/dist/components/StatusIndicator.d.ts +0 -8
  80. package/dist/components/TextInput.d.ts +0 -10
  81. package/dist/components/TextInput.js +0 -29
  82. package/dist/components/WelcomeScreen.d.ts +0 -14
  83. package/dist/types/index.d.ts +0 -284
  84. package/dist/utils/branding.d.ts +0 -28
  85. package/dist/utils/config.d.ts +0 -17
  86. package/dist/utils/jsonc.d.ts +0 -19
  87. package/dist/utils/keychain.d.ts +0 -15
  88. package/dist/utils/oauth2-auth.d.ts +0 -27
  89. package/dist/utils/password-prompt.d.ts +0 -14
  90. package/dist/utils/process-runner.d.ts +0 -22
  91. package/dist/utils/project-detection.d.ts +0 -151
  92. package/dist/utils/session-cookie-auth.d.ts +0 -34
  93. package/dist/utils/signing-password.d.ts +0 -12
  94. package/dist/utils/signing-step.d.ts +0 -15
  95. package/dist/utils/signing-step.js +0 -16
  96. package/dist/utils/sitevision-api.d.ts +0 -112
  97. package/dist/utils/sitevision-scripts-runner.d.ts +0 -83
  98. package/dist/utils/version-check.d.ts +0 -9
  99. package/dist/utils/webpack-runner.d.ts +0 -76
  100. package/dist/utils/zip.d.ts +0 -71
@@ -1,210 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- import { TextInput } from './TextInput.js';
5
- import { writeDevProperties } from '../utils/project-detection.js';
6
- import { setDeployPassword, deleteDeployPassword, setOAuth2ClientSecret, } from '../utils/keychain.js';
7
- import { DEFAULT_REDIRECT_PORT } from '../utils/oauth2-auth.js';
8
- const LABELS = {
9
- domain: 'Domain',
10
- siteName: 'Site Name',
11
- addonName: 'Addon Name',
12
- username: 'Username',
13
- authMethod: 'Auth Method',
14
- password: 'Password',
15
- oauthClientId: 'Client ID',
16
- oauthAuthEndpoint: 'Authorization Endpoint',
17
- oauthTokenEndpoint: 'Token Endpoint',
18
- oauthScopes: 'Scopes',
19
- oauthClientSecret: 'Client Secret',
20
- sessionLoginUrl: 'Login URL',
21
- useHTTP: 'Use HTTP',
22
- };
23
- const AUTH_METHODS = [
24
- { value: 'basic', label: 'Basic auth (username + password)' },
25
- { value: 'oauth2', label: 'OAuth2 bearer token (PKCE)' },
26
- { value: 'cookie', label: 'Session cookie (SAML / SSO login)' },
27
- ];
28
- function parseScopes(raw) {
29
- const scopes = raw
30
- .split(/[\s,]+/)
31
- .map(s => s.trim())
32
- .filter(Boolean);
33
- return scopes.length > 0 ? scopes : undefined;
34
- }
35
- export function DevPropertiesForm({ projectRoot, initialProperties, packageJson, onComplete, onCancel, }) {
36
- const [stepIndex, setStepIndex] = useState(0);
37
- const [properties, setProperties] = useState(() => {
38
- const defaults = {
39
- domain: packageJson.developmentDomain || '',
40
- addonName: packageJson.addonName || '',
41
- siteName: packageJson.siteName || '',
42
- authMethod: 'basic',
43
- };
44
- return { ...defaults, ...initialProperties };
45
- });
46
- const [oauth, setOauth] = useState(() => ({
47
- authorizationEndpoint: initialProperties?.oauth2?.authorizationEndpoint ?? '',
48
- tokenEndpoint: initialProperties?.oauth2?.tokenEndpoint ?? '',
49
- clientId: initialProperties?.oauth2?.clientId ?? '',
50
- scopes: initialProperties?.oauth2?.scopes?.join(' ') ?? '',
51
- clientSecret: '',
52
- }));
53
- const method = properties.authMethod ?? 'basic';
54
- const isOAuth = method === 'oauth2';
55
- const methodSteps = method === 'oauth2'
56
- ? [
57
- 'oauthClientId',
58
- 'oauthAuthEndpoint',
59
- 'oauthTokenEndpoint',
60
- 'oauthScopes',
61
- 'oauthClientSecret',
62
- ]
63
- : method === 'cookie'
64
- ? ['sessionLoginUrl']
65
- : ['password'];
66
- const steps = [
67
- 'domain',
68
- 'siteName',
69
- 'addonName',
70
- 'username',
71
- 'authMethod',
72
- ...methodSteps,
73
- 'useHTTP',
74
- ];
75
- const currentStep = steps[stepIndex];
76
- const redirectPort = initialProperties?.oauth2?.redirectPort ?? DEFAULT_REDIRECT_PORT;
77
- const advance = () => {
78
- if (stepIndex < steps.length - 1) {
79
- setStepIndex(stepIndex + 1);
80
- }
81
- };
82
- const finalize = (props, fields) => {
83
- const authMethod = props.authMethod ?? 'basic';
84
- const domain = props.domain ?? '';
85
- const username = props.username ?? '';
86
- const finalProps = {
87
- domain,
88
- siteName: props.siteName ?? '',
89
- addonName: props.addonName ?? '',
90
- username,
91
- authMethod,
92
- useHTTPForDevDeploy: props.useHTTPForDevDeploy ?? false,
93
- };
94
- if (authMethod === 'oauth2') {
95
- finalProps.oauth2 = {
96
- authorizationEndpoint: fields.authorizationEndpoint,
97
- tokenEndpoint: fields.tokenEndpoint,
98
- clientId: fields.clientId,
99
- scopes: parseScopes(fields.scopes),
100
- ...(initialProperties?.oauth2?.redirectPort && {
101
- redirectPort: initialProperties.oauth2.redirectPort,
102
- }),
103
- };
104
- if (fields.clientSecret && domain && fields.clientId) {
105
- setOAuth2ClientSecret(domain, fields.clientId, fields.clientSecret);
106
- }
107
- }
108
- else if (authMethod === 'cookie') {
109
- if (props.sessionLoginUrl) {
110
- finalProps.sessionLoginUrl = props.sessionLoginUrl;
111
- }
112
- }
113
- else if (props.password && domain && username) {
114
- setDeployPassword(domain, username, props.password);
115
- }
116
- else if (domain && username) {
117
- // Empty password — clear any stale keychain entry so deploy prompts.
118
- deleteDeployPassword(domain, username);
119
- }
120
- writeDevProperties(projectRoot, finalProps);
121
- onComplete();
122
- };
123
- // Update a top-level DevProperties field, then advance or finalize.
124
- const submitProperty = (key, value) => {
125
- const next = { ...properties, [key]: value };
126
- setProperties(next);
127
- if (steps[stepIndex] === steps[steps.length - 1]) {
128
- finalize(next, oauth);
129
- }
130
- else {
131
- advance();
132
- }
133
- };
134
- // Update an OAuth field, then advance or finalize.
135
- const submitOAuth = (key, value) => {
136
- const next = { ...oauth, [key]: value };
137
- setOauth(next);
138
- if (steps[stepIndex] === steps[steps.length - 1]) {
139
- finalize(properties, next);
140
- }
141
- else {
142
- advance();
143
- }
144
- };
145
- const renderInput = () => {
146
- switch (currentStep) {
147
- case 'domain':
148
- return (_jsx(TextInput, { label: "Development Domain (e.g. www.sitevision.se)", defaultValue: properties.domain, placeholder: "sitevision.se", onSubmit: value => submitProperty('domain', value), onCancel: onCancel }, "domain"));
149
- case 'siteName':
150
- return (_jsx(TextInput, { label: "Site Name (Root node name)", defaultValue: properties.siteName, onSubmit: value => submitProperty('siteName', value), onCancel: onCancel }, "siteName"));
151
- case 'addonName':
152
- return (_jsx(TextInput, { label: "Addon Name", defaultValue: properties.addonName, onSubmit: value => submitProperty('addonName', value), onCancel: onCancel }, "addonName"));
153
- case 'username':
154
- return (_jsx(TextInput, { label: "Username (usually your Sitevision Cloud email)", defaultValue: properties.username, onSubmit: value => submitProperty('username', value), onCancel: onCancel }, "username"));
155
- case 'authMethod':
156
- return (_jsx(MethodSelect, { defaultValue: method, onSubmit: value => submitProperty('authMethod', value) }, "authMethod"));
157
- case 'password':
158
- return (_jsx(TextInput, { label: "Password (saved in OS keychain \u2014 leave empty to prompt on each run)", type: "password", defaultValue: properties.password, onSubmit: value => submitProperty('password', value), onCancel: onCancel }, "password"));
159
- case 'oauthClientId':
160
- return (_jsx(TextInput, { label: "OAuth2 Client ID", defaultValue: oauth.clientId, onSubmit: value => submitOAuth('clientId', value), onCancel: onCancel }, "oauthClientId"));
161
- case 'oauthAuthEndpoint':
162
- return (_jsx(TextInput, { label: "Authorization Endpoint URL", defaultValue: oauth.authorizationEndpoint, onSubmit: value => submitOAuth('authorizationEndpoint', value), onCancel: onCancel }, "oauthAuthEndpoint"));
163
- case 'oauthTokenEndpoint':
164
- return (_jsx(TextInput, { label: "Token Endpoint URL", defaultValue: oauth.tokenEndpoint, onSubmit: value => submitOAuth('tokenEndpoint', value), onCancel: onCancel }, "oauthTokenEndpoint"));
165
- case 'oauthScopes':
166
- return (_jsx(TextInput, { label: "Scopes (space-separated, optional)", defaultValue: oauth.scopes, onSubmit: value => submitOAuth('scopes', value), onCancel: onCancel }, "oauthScopes"));
167
- case 'oauthClientSecret':
168
- return (_jsx(TextInput, { label: "Client Secret (OS keychain \u2014 leave empty for a public/PKCE client)", type: "password", defaultValue: oauth.clientSecret, onSubmit: value => submitOAuth('clientSecret', value), onCancel: onCancel }, "oauthClientSecret"));
169
- case 'sessionLoginUrl':
170
- return (_jsx(TextInput, { label: "Login URL (opened in a browser; blank = site root)", defaultValue: properties.sessionLoginUrl ??
171
- (properties.domain ? `https://${properties.domain}/` : ''), onSubmit: value => submitProperty('sessionLoginUrl', value), onCancel: onCancel }, "sessionLoginUrl"));
172
- case 'useHTTP':
173
- return (_jsx(BooleanInput, { label: "Use HTTP for deployment? (y/n)", defaultValue: properties.useHTTPForDevDeploy ?? false, onSubmit: value => submitProperty('useHTTPForDevDeploy', value) }, "useHTTP"));
174
- default:
175
- return null;
176
- }
177
- };
178
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Setup Development Properties" }), _jsxs(Text, { children: [' ', "Step ", stepIndex + 1, " of ", steps.length, ":", ' ', currentStep ? LABELS[currentStep] : ''] })] }), isOAuth && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: ["Whitelist this redirect URI on the OAuth2 client: http://127.0.0.1:", redirectPort, "/callback"] }) })), _jsx(Box, { marginBottom: 1, children: steps.map((s, i) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: i <= stepIndex ? 'green' : 'gray', children: i < stepIndex ? '✓' : i === stepIndex ? '●' : '○' }) }, s))) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", padding: 1, children: renderInput() })] }));
179
- }
180
- function MethodSelect({ defaultValue, onSubmit, }) {
181
- const [index, setIndex] = useState(() => Math.max(0, AUTH_METHODS.findIndex(m => m.value === defaultValue)));
182
- useInput((_input, key) => {
183
- if (key.upArrow) {
184
- setIndex(p => (p === 0 ? AUTH_METHODS.length - 1 : p - 1));
185
- }
186
- else if (key.downArrow) {
187
- setIndex(p => (p === AUTH_METHODS.length - 1 ? 0 : p + 1));
188
- }
189
- else if (key.return) {
190
- onSubmit(AUTH_METHODS[index].value);
191
- }
192
- });
193
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Authentication method" }) }), AUTH_METHODS.map((m, i) => (_jsxs(Text, { color: i === index ? 'green' : undefined, children: [i === index ? '❯ ' : ' ', m.label] }, m.value))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move, Enter to select" }) })] }));
194
- }
195
- function BooleanInput({ label, defaultValue, onSubmit, }) {
196
- useInput(input => {
197
- if (input === 'y' || input === 'Y') {
198
- onSubmit(true);
199
- }
200
- else if (input === 'n' || input === 'N') {
201
- onSubmit(false);
202
- }
203
- else if (input === '\r' && defaultValue !== undefined) {
204
- onSubmit(defaultValue);
205
- }
206
- });
207
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: label }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["Press Y for Yes, N for No", defaultValue !== undefined
208
- ? ` (Default: ${defaultValue ? 'Yes' : 'No'})`
209
- : ''] }) })] }));
210
- }
@@ -1,7 +0,0 @@
1
- import { type ProjectInfo } from '../utils/project-detection.js';
2
- interface Props {
3
- project: ProjectInfo;
4
- onBack: () => void;
5
- }
6
- export declare function InfoScreen({ project, onBack }: Props): import("react").JSX.Element;
7
- export {};
@@ -1,14 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Box, Text, useInput } from 'ink';
3
- import { getAppType, localizedText, } from '../utils/project-detection.js';
4
- import { checkSitevisionScriptsCompatibility } from '../utils/sitevision-scripts-runner.js';
5
- export function InfoScreen({ project, onBack }) {
6
- const appType = getAppType(project.manifest);
7
- const scriptsCompat = checkSitevisionScriptsCompatibility(project.root);
8
- useInput((input, key) => {
9
- if (key.escape || input === 'q' || key.return) {
10
- onBack();
11
- }
12
- });
13
- 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: localizedText(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' })] })] }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Build Tooling" }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "sitevision-scripts: " }), _jsx(Text, { children: scriptsCompat.installed ?? 'not installed' }), _jsxs(Text, { dimColor: true, children: [" (supported ", scriptsCompat.supportedRange, ")"] })] }), scriptsCompat.warning && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["\u26A0 ", scriptsCompat.warning] }) }))] }), 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: _jsx(Text, { color: "yellow", children: "\u26A0 No dev properties found. Run setup-dev-properties to configure." }) })), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { bold: true, children: "Project Root: " }), _jsx(Text, { dimColor: true, children: project.root })] }), _jsx(Box, { marginTop: 2, children: _jsx(Text, { dimColor: true, children: "Press Enter or ESC to return to menu" }) })] }));
14
- }
@@ -1,8 +0,0 @@
1
- interface Props {
2
- label?: string;
3
- onUseSaved: () => void;
4
- onEnterNew: () => void;
5
- onCancel: () => void;
6
- }
7
- export declare function KeychainPasswordChoice({ label, onUseSaved, onEnterNew, onCancel, }: Props): import("react").JSX.Element;
8
- export {};
@@ -1,30 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- const OPTIONS = [
5
- { label: 'Use saved password from keychain', value: 'saved' },
6
- { label: 'Enter a new password', value: 'new' },
7
- ];
8
- export function KeychainPasswordChoice({ label = 'A signing password is saved in your OS keychain.', onUseSaved, onEnterNew, onCancel, }) {
9
- const [selectedIndex, setSelectedIndex] = useState(0);
10
- useInput((_input, key) => {
11
- if (key.upArrow) {
12
- setSelectedIndex(prev => (prev === 0 ? OPTIONS.length - 1 : prev - 1));
13
- }
14
- else if (key.downArrow) {
15
- setSelectedIndex(prev => (prev === OPTIONS.length - 1 ? 0 : prev + 1));
16
- }
17
- else if (key.return) {
18
- if (selectedIndex === 0) {
19
- onUseSaved();
20
- }
21
- else {
22
- onEnterNew();
23
- }
24
- }
25
- else if (key.escape) {
26
- onCancel();
27
- }
28
- });
29
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: label }) }), OPTIONS.map((option, index) => (_jsxs(Text, { color: index === selectedIndex ? 'green' : undefined, children: [index === selectedIndex ? '❯ ' : ' ', option.label] }, option.value))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move, Enter to select, Esc to cancel" }) })] }));
30
- }
@@ -1,7 +0,0 @@
1
- import { type ProjectInfo } from '../utils/project-detection.js';
2
- interface Props {
3
- project: ProjectInfo;
4
- onSelect: (command: string) => void;
5
- }
6
- export declare function MainMenu({ project, onSelect }: Props): import("react").JSX.Element;
7
- export {};
@@ -1,83 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- import { getAppType, localizedText } from '../utils/project-detection.js';
5
- export function MainMenu({ project, onSelect }) {
6
- const appType = getAppType(project.manifest);
7
- const [selectedIndex, setSelectedIndex] = useState(0);
8
- const items = [
9
- {
10
- label: '🚀 Dev',
11
- value: 'dev',
12
- description: 'Start development server with watch mode',
13
- },
14
- {
15
- label: '🔐 Dev (Signed)',
16
- value: 'dev-signed',
17
- description: 'Development with automatic signing',
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
- },
29
- {
30
- label: '🔨 Build',
31
- value: 'build',
32
- description: 'Build the application for production',
33
- },
34
- {
35
- label: 'âœī¸ Sign',
36
- value: 'sign',
37
- description: 'Sign the app for production deployment',
38
- },
39
- {
40
- label: 'đŸ“Ļ Deploy',
41
- value: 'deploy',
42
- description: 'Deploy to development server',
43
- },
44
- {
45
- label: 'đŸšĸ Deploy (Force)',
46
- value: 'deploy-force',
47
- description: 'Force deploy (overwrite existing)',
48
- },
49
- {
50
- label: '🌍 Deploy Production',
51
- value: 'deploy-production',
52
- description: 'Deploy to production server',
53
- },
54
- {
55
- label: 'â„šī¸ Info',
56
- value: 'info',
57
- description: 'Show project information',
58
- },
59
- {
60
- label: '❌ Exit',
61
- value: 'exit',
62
- description: 'Exit the CLI',
63
- },
64
- ];
65
- useInput((input, key) => {
66
- if (key.upArrow) {
67
- setSelectedIndex(prev => (prev > 0 ? prev - 1 : items.length - 1));
68
- }
69
- if (key.downArrow) {
70
- setSelectedIndex(prev => (prev < items.length - 1 ? prev + 1 : 0));
71
- }
72
- if (key.return || input === '\r' || input === '\n') {
73
- const selectedItem = items[selectedIndex];
74
- if (!selectedItem)
75
- return;
76
- if (selectedItem.value === 'exit') {
77
- process.exit(0);
78
- }
79
- onSelect(selectedItem.value);
80
- }
81
- });
82
- 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, marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Name: " }), _jsx(Text, { children: localizedText(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, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Development Configuration" }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, 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.hasSigningProperties && project.devProperties && (_jsxs(_Fragment, { children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Signing Configuration" }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Signing User: " }), _jsx(Text, { children: project.devProperties.signingUsername })] }), project.devProperties.certificateName && (_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Certificate: " }), _jsx(Text, { children: project.devProperties.certificateName })] }))] })] })), !project.hasDevProperties && (_jsx(Box, { marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "yellow", children: _jsx(Text, { color: "yellow", children: "\u26A0 No dev properties found. Some commands may not work." }) })), project.hasDevProperties && !project.hasSigningProperties && (_jsx(Box, { marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "yellow", children: _jsx(Text, { color: "yellow", children: "\u26A0 No signing credentials configured. Run svc setup-signing to configure." }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Select a command:" }) }), _jsx(Box, { flexDirection: "column", children: items.map((item, index) => (_jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: index === selectedIndex ? 'cyan' : undefined, bold: index === selectedIndex, children: [index === selectedIndex ? 'â–ļ ' : ' ', item.label, item.description && _jsxs(Text, { dimColor: true, children: [" - ", item.description] })] }) }, item.value))) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 arrows to navigate, Enter to select" }) })] }));
83
- }
@@ -1,10 +0,0 @@
1
- interface Props {
2
- label?: string;
3
- showRememberOption?: boolean;
4
- defaultRemember?: boolean;
5
- rememberLabel?: string;
6
- onSubmit: (password: string, remember: boolean) => void;
7
- onCancel: () => void;
8
- }
9
- export declare function PasswordInput({ label, showRememberOption, defaultRemember, rememberLabel, onSubmit, onCancel, }: Props): import("react").JSX.Element;
10
- export {};
@@ -1,6 +0,0 @@
1
- import { ProcessRunner } from '../utils/process-runner.js';
2
- interface Props {
3
- runner: ProcessRunner;
4
- }
5
- export declare function ProcessOutputComponent({ runner }: Props): import("react").JSX.Element;
6
- export {};
@@ -1,30 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text } from 'ink';
4
- export function ProcessOutputComponent({ runner }) {
5
- const [outputs, setOutputs] = useState([]);
6
- const [isRunning, setIsRunning] = useState(true);
7
- const [exitCode, setExitCode] = useState(null);
8
- useEffect(() => {
9
- const handleOutput = (output) => {
10
- setOutputs(prev => {
11
- const newOutputs = [...prev, output];
12
- if (newOutputs.length > 100) {
13
- return newOutputs.slice(newOutputs.length - 100);
14
- }
15
- return newOutputs;
16
- });
17
- };
18
- const handleExit = (code) => {
19
- setIsRunning(false);
20
- setExitCode(code);
21
- };
22
- runner.on('output', handleOutput);
23
- runner.on('exit', handleExit);
24
- return () => {
25
- runner.off('output', handleOutput);
26
- runner.off('exit', handleExit);
27
- };
28
- }, [runner]);
29
- return (_jsxs(Box, { flexDirection: "column", children: [outputs.map((output, index) => (_jsx(Text, { color: output.type === 'stderr' ? 'red' : undefined, dimColor: output.type === 'stderr', children: output.data }, index))), !isRunning && exitCode !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: exitCode === 0 ? 'green' : 'red', children: exitCode === 0 ? '✓ Success' : `✗ Failed with code ${exitCode}` }) }))] }));
30
- }
@@ -1,8 +0,0 @@
1
- import { type ProjectInfo } from '../utils/project-detection.js';
2
- interface Props {
3
- project: ProjectInfo;
4
- onReload: () => void;
5
- onComplete: () => void;
6
- }
7
- export declare function SetupFlow({ project, onReload, onComplete }: Props): import("react").JSX.Element | null;
8
- export {};