sitevision-cli 1.0.0-beta.8 → 1.0.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 (100) hide show
  1. package/CHANGELOG.md +138 -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 +44 -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 +162 -32
  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 +27 -4
  49. package/readme.md +113 -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,233 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- import { getAppType, localizedText, migrateLegacyPassword, getPackageJsonSyncChanges, syncDevPropertiesToPackageJson, readSvcConfig, writeSvcConfig, writeDevProperties, } from '../utils/project-detection.js';
5
- import { ProcessRunner } from '../utils/process-runner.js';
6
- import { ProcessOutputComponent } from './ProcessOutput.js';
7
- import { StatusIndicator } from './StatusIndicator.js';
8
- import { DevPropertiesForm } from './DevPropertiesForm.js';
9
- import { SigningPropertiesForm } from './SigningPropertiesForm.js';
10
- export function SetupFlow({ project, onReload, onComplete }) {
11
- const [step, setStep] = useState('check-node-modules');
12
- const [runner, setRunner] = useState(null);
13
- const [commandStatus, setCommandStatus] = useState('running');
14
- const [syncChanges, setSyncChanges] = useState([]);
15
- const [syncDecision, setSyncDecision] = useState(false);
16
- // Set when the user picks OAuth2 for an existing config, so the form opens in
17
- // the OAuth2 branch without mutating the shared project object.
18
- const [pendingAuthMethod, setPendingAuthMethod] = useState(undefined);
19
- const appType = getAppType(project.manifest);
20
- // Auto-advance through checks
21
- useEffect(() => {
22
- if (step === 'check-node-modules') {
23
- if (project.hasNodeModules) {
24
- setStep('check-dev-properties');
25
- }
26
- else {
27
- setStep('confirm-npm-install');
28
- }
29
- }
30
- else if (step === 'check-dev-properties') {
31
- if (project.hasDevProperties) {
32
- if (project.hasLegacyPassword) {
33
- setStep('confirm-password-migration');
34
- }
35
- else if (project.devProperties?.authMethod === undefined) {
36
- setStep('confirm-auth-method');
37
- }
38
- else {
39
- setStep('check-package-sync');
40
- }
41
- }
42
- else {
43
- setStep('confirm-dev-setup');
44
- }
45
- }
46
- else if (step === 'check-package-sync') {
47
- const preference = readSvcConfig(project.root).syncPackageJson;
48
- const properties = project.devProperties;
49
- const changes = preference !== false && properties
50
- ? getPackageJsonSyncChanges(project.root, properties)
51
- : [];
52
- if (changes.length === 0 || !properties) {
53
- setStep('check-signing-properties');
54
- }
55
- else if (preference === true) {
56
- syncDevPropertiesToPackageJson(project.root, properties);
57
- onReload();
58
- setStep('check-signing-properties');
59
- }
60
- else {
61
- setSyncChanges(changes);
62
- setStep('confirm-package-sync');
63
- }
64
- }
65
- else if (step === 'check-signing-properties') {
66
- if (project.hasSigningProperties) {
67
- setStep('show-info');
68
- }
69
- else {
70
- setStep('confirm-signing-setup');
71
- }
72
- }
73
- else if (step === 'show-info') {
74
- // Auto-advance to menu after displaying info
75
- onComplete();
76
- }
77
- }, [step, project, onComplete]); // Removed specific props from dependency array to allow re-check after updates
78
- useInput(input => {
79
- if (step === 'confirm-npm-install') {
80
- if (input === 'y' || input === 'Y') {
81
- setStep('running-npm-install');
82
- setCommandStatus('running');
83
- // npm install is a native command, not a script
84
- const newRunner = new ProcessRunner('npm', ['install'], project.root);
85
- newRunner.on('exit', (code) => {
86
- if (code === 0) {
87
- setCommandStatus('success');
88
- // Force project info refresh would be ideal here
89
- // For now, assume success and move on
90
- setTimeout(() => setStep('check-dev-properties'), 1000);
91
- }
92
- else {
93
- setCommandStatus('error');
94
- }
95
- });
96
- setRunner(newRunner);
97
- newRunner.run().catch(() => setCommandStatus('error'));
98
- }
99
- else if (input === 'n' || input === 'N') {
100
- setStep('check-dev-properties');
101
- }
102
- }
103
- else if (step === 'confirm-dev-setup') {
104
- if (input === 'y' || input === 'Y') {
105
- setStep('setup-dev-properties');
106
- }
107
- else if (input === 'n' || input === 'N') {
108
- setStep('check-signing-properties');
109
- }
110
- }
111
- else if (step === 'confirm-password-migration') {
112
- if (input === 'y' || input === 'Y') {
113
- migrateLegacyPassword(project);
114
- // The file was rewritten (plaintext stripped, password moved to
115
- // keychain) — re-detect so hasLegacyPassword/password reflect that.
116
- onReload();
117
- setStep('check-package-sync');
118
- }
119
- else if (input === 'n' || input === 'N') {
120
- setStep('check-package-sync');
121
- }
122
- }
123
- else if (step === 'confirm-package-sync') {
124
- if (['y', 'Y', 'n', 'N'].includes(input)) {
125
- const accepted = input.toLowerCase() === 'y';
126
- if (accepted && project.devProperties) {
127
- syncDevPropertiesToPackageJson(project.root, project.devProperties);
128
- onReload();
129
- }
130
- setSyncDecision(accepted);
131
- setStep('confirm-save-sync-choice');
132
- }
133
- }
134
- else if (step === 'confirm-save-sync-choice') {
135
- if (input === 'y' || input === 'Y') {
136
- writeSvcConfig(project.root, { syncPackageJson: syncDecision });
137
- setStep('check-signing-properties');
138
- }
139
- else if (input === 'n' || input === 'N') {
140
- setStep('check-signing-properties');
141
- }
142
- }
143
- else if (step === 'confirm-signing-setup') {
144
- if (input === 'y' || input === 'Y') {
145
- setStep('setup-signing-properties');
146
- }
147
- else if (input === 'n' || input === 'N') {
148
- setStep('show-info');
149
- }
150
- }
151
- else if (step === 'confirm-auth-method') {
152
- if (input === 'o' || input === 'O') {
153
- // Choosing OAuth2 needs endpoints — collect them in the full form.
154
- setPendingAuthMethod('oauth2');
155
- setStep('setup-dev-properties');
156
- }
157
- else if (input === 'c' || input === 'C') {
158
- setPendingAuthMethod('cookie');
159
- setStep('setup-dev-properties');
160
- }
161
- else if (['b', 'B', '\r'].includes(input)) {
162
- if (project.devProperties) {
163
- writeDevProperties(project.root, {
164
- ...project.devProperties,
165
- authMethod: 'basic',
166
- });
167
- onReload();
168
- }
169
- setStep('check-package-sync');
170
- }
171
- }
172
- });
173
- // Setup Dev Properties Form
174
- if (step === 'setup-dev-properties') {
175
- return (_jsx(DevPropertiesForm, { projectRoot: project.root, initialProperties: pendingAuthMethod && project.devProperties
176
- ? { ...project.devProperties, authMethod: pendingAuthMethod }
177
- : project.devProperties, packageJson: project.packageJson, onComplete: () => {
178
- // Re-detect from disk/keychain so devProperties (incl. the keychain
179
- // password) populate in memory — otherwise the rest of this flow and
180
- // the menu would see stale state until the CLI is restarted.
181
- onReload();
182
- setStep('check-package-sync');
183
- }, onCancel: () => setStep('check-signing-properties') }));
184
- }
185
- // Setup Signing Properties Form
186
- if (step === 'setup-signing-properties') {
187
- return (_jsx(SigningPropertiesForm, { projectRoot: project.root, onComplete: () => {
188
- // Re-detect so signing credentials are reflected in memory before
189
- // the info screen / menu render.
190
- onReload();
191
- setStep('show-info');
192
- }, onCancel: () => setStep('show-info') }));
193
- }
194
- // Running npm install
195
- if (step === 'running-npm-install') {
196
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(StatusIndicator, { status: commandStatus, label: "Installing dependencies" }) }), runner && _jsx(ProcessOutputComponent, { runner: runner })] }));
197
- }
198
- // Confirm npm install
199
- if (step === 'confirm-npm-install') {
200
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 node_modules not found" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Would you like to run npm install? (y/n)" }) })] }));
201
- }
202
- // Confirm dev setup
203
- if (step === 'confirm-dev-setup') {
204
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 dev properties not configured" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Would you like to set up dev properties? (y/n)" }) })] }));
205
- }
206
- // Confirm legacy password migration
207
- if (step === 'confirm-password-migration') {
208
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 Plaintext password found in .dev_properties.json" }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Move it to the OS keychain and remove it from the file? (y/n)" }), _jsx(Text, { dimColor: true, children: "Recommended \u2014 storing passwords in project files is insecure." })] })] }));
209
- }
210
- // Ask which auth method an existing config should use (setting is missing)
211
- if (step === 'confirm-auth-method') {
212
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 Deploy authentication method not set" }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Which method should deploys use? [B]asic / [O]Auth2 / [C]ookie" }), _jsx(Text, { dimColor: true, children: "B = Basic (default), O = OAuth2 bearer, C = session cookie (SSO)." })] })] }));
213
- }
214
- // Confirm package.json sync
215
- if (step === 'confirm-package-sync') {
216
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 package.json is out of sync with .dev_properties.json" }) }), _jsx(Box, { marginBottom: 1, flexDirection: "column", marginLeft: 2, children: syncChanges.map(change => (_jsxs(Box, { children: [_jsx(Text, { color: change.from === undefined ? 'green' : 'yellow', children: change.from === undefined ? '+ ' : '~ ' }), _jsxs(Text, { bold: true, children: [change.key, ": "] }), change.from !== undefined && (_jsxs(Text, { dimColor: true, children: [change.from, " \u2192 "] })), _jsx(Text, { children: change.to })] }, change.key))) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Update package.json from .dev_properties.json? (y/n)" }), _jsx(Text, { dimColor: true, children: "sitevision-scripts reads these fields from package.json." })] })] }));
217
- }
218
- // Offer to persist the sync decision in .svcconfig
219
- if (step === 'confirm-save-sync-choice') {
220
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Remember this choice in .svcconfig? (y/n)" }), _jsx(Text, { dimColor: true, children: syncDecision
221
- ? 'svc will update package.json automatically from now on.'
222
- : 'svc will stop asking about package.json sync.' })] })] }));
223
- }
224
- // Confirm signing setup
225
- if (step === 'confirm-signing-setup') {
226
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Sitevision CLI" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 signing credentials not configured" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Signing credentials are required for signing apps on developer.sitevision.se" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Would you like to set up signing credentials? (y/n)" }) })] }));
227
- }
228
- // Show info
229
- if (step === 'show-info') {
230
- 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' })] })] }), 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 configured" }) })), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { bold: true, children: "Project Root: " }), _jsx(Text, { dimColor: true, children: project.root })] })] }));
231
- }
232
- return null;
233
- }
@@ -1,7 +0,0 @@
1
- interface Props {
2
- projectRoot: string;
3
- onComplete: () => void;
4
- onCancel: () => void;
5
- }
6
- export declare function SigningPropertiesForm({ projectRoot, onComplete, onCancel, }: Props): import("react").JSX.Element;
7
- export {};
@@ -1,38 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text } from 'ink';
4
- import { TextInput } from './TextInput.js';
5
- import { writeDevProperties, readDevProperties, } from '../utils/project-detection.js';
6
- const STEPS = [
7
- { id: 'username', label: 'Signing Username' },
8
- { id: 'certificate', label: 'Certificate Name' },
9
- ];
10
- export function SigningPropertiesForm({ projectRoot, onComplete, onCancel, }) {
11
- const [stepIndex, setStepIndex] = useState(0);
12
- // Read existing properties to preserve other fields
13
- const [properties, setProperties] = useState(() => readDevProperties(projectRoot) || {});
14
- const currentStep = STEPS[stepIndex];
15
- const handleNext = (key, value) => {
16
- const newProperties = { ...properties, [key]: value };
17
- setProperties(newProperties);
18
- if (stepIndex < STEPS.length - 1) {
19
- setStepIndex(stepIndex + 1);
20
- }
21
- else {
22
- // Save and finish
23
- writeDevProperties(projectRoot, newProperties);
24
- onComplete();
25
- }
26
- };
27
- const renderInput = () => {
28
- switch (currentStep?.id) {
29
- case 'username':
30
- return (_jsx(TextInput, { label: "Signing Username (developer.sitevision.se)", defaultValue: properties.signingUsername, onSubmit: (value) => handleNext('signingUsername', value), onCancel: onCancel }, "username"));
31
- case 'certificate':
32
- return (_jsx(TextInput, { label: "Certificate Name (Optional)", defaultValue: properties.certificateName, placeholder: "Leave empty for default", onSubmit: (value) => handleNext('certificateName', value), onCancel: onCancel }, "certificate"));
33
- default:
34
- return null;
35
- }
36
- };
37
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Setup Signing Properties" }), _jsxs(Text, { children: [' ', "Step ", stepIndex + 1, " of ", STEPS.length, ": ", currentStep?.label] })] }), _jsx(Box, { marginBottom: 1, children: STEPS.map((s, i) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: i === stepIndex ? 'green' : i < stepIndex ? 'green' : 'gray', children: i < stepIndex ? '✓' : i === stepIndex ? '●' : '○' }) }, s.id))) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", padding: 1, children: renderInput() })] }));
38
- }
@@ -1,8 +0,0 @@
1
- export type Status = 'pending' | 'running' | 'success' | 'error';
2
- interface Props {
3
- status: Status;
4
- label: string;
5
- message?: string;
6
- }
7
- export declare function StatusIndicator({ status, label, message }: Props): import("react").JSX.Element;
8
- export {};
@@ -1,10 +0,0 @@
1
- interface Props {
2
- label: string;
3
- defaultValue?: string;
4
- placeholder?: string;
5
- onSubmit: (value: string) => void;
6
- onCancel?: () => void;
7
- type?: 'text' | 'password';
8
- }
9
- export declare function TextInput({ label, defaultValue, placeholder, onSubmit, onCancel, type, }: Props): import("react").JSX.Element;
10
- export {};
@@ -1,29 +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
- export function TextInput({ label, defaultValue = '', placeholder, onSubmit, onCancel, type = 'text', }) {
5
- const [value, setValue] = useState(defaultValue);
6
- useInput((input, key) => {
7
- if (key.return) {
8
- if (value === '' && defaultValue) {
9
- onSubmit(defaultValue);
10
- }
11
- else {
12
- onSubmit(value);
13
- }
14
- return;
15
- }
16
- if (key.escape && onCancel) {
17
- onCancel();
18
- return;
19
- }
20
- if (key.delete || key.backspace) {
21
- setValue(prev => prev.slice(0, -1));
22
- return;
23
- }
24
- if (!key.ctrl && !key.meta) {
25
- setValue(prev => prev + input);
26
- }
27
- });
28
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: label }) }), _jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { children: type === 'password' ? '*'.repeat(value.length) : value }), value === '' && placeholder && _jsx(Text, { dimColor: true, children: placeholder })] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press Enter to submit", onCancel ? ', Esc to cancel' : ''] }) })] }));
29
- }
@@ -1,14 +0,0 @@
1
- import { type ProjectInfo } from '../utils/project-detection.js';
2
- interface Props {
3
- project: ProjectInfo;
4
- onComplete: () => void;
5
- }
6
- /**
7
- * First-run welcome screen. Shows the branding once and, when signing
8
- * credentials are configured but no password is stored yet, offers to save the
9
- * signing password to the OS keychain. If signing isn't set up, it just shows
10
- * the branding — the user can still save a signing password later (the regular
11
- * signing flow offers a "remember" option every time).
12
- */
13
- export declare function WelcomeScreen({ project, onComplete }: Props): import("react").JSX.Element;
14
- export {};
@@ -1,284 +0,0 @@
1
- /**
2
- * Sitevision CLI - Shared Type Definitions
3
- *
4
- * This file contains all shared types used across the CLI.
5
- */
6
- /**
7
- * App types supported by Sitevision
8
- */
9
- export type AppType = 'WebApp' | 'Widget' | 'RESTApp';
10
- /**
11
- * Simplified app type for internal use
12
- */
13
- export type SimpleAppType = 'web' | 'widget' | 'rest';
14
- /**
15
- * A manifest text field that may be a plain string or a localized object keyed
16
- * by language code, e.g. `{sv: 'Namn', en: 'Name'}`. Sitevision allows either
17
- * form for human-facing fields like `name` and `description`.
18
- */
19
- export type LocalizedString = string | Record<string, string>;
20
- /**
21
- * Sitevision app manifest (manifest.json)
22
- */
23
- export interface SitevisionManifest {
24
- id: string;
25
- name: LocalizedString;
26
- version: string;
27
- type: AppType;
28
- bundled?: boolean;
29
- description?: LocalizedString;
30
- author?: string;
31
- helpUrl?: string;
32
- license?: string;
33
- categories?: string[];
34
- }
35
- /**
36
- * Development properties.
37
- *
38
- * Persisted fields live in .dev_properties.json. `password` is runtime-only:
39
- * resolved from the OS keychain (or a legacy plaintext file during migration)
40
- * and never written back to disk.
41
- */
42
- export interface DevProperties {
43
- domain: string;
44
- siteName: string;
45
- addonName: string;
46
- username: string;
47
- password?: string;
48
- useHTTPForDevDeploy?: boolean;
49
- signingUsername?: string;
50
- certificateName?: string;
51
- authMethod?: 'basic' | 'oauth2' | 'cookie';
52
- oauth2?: OAuth2Config;
53
- sessionLoginUrl?: string;
54
- accessToken?: string;
55
- sessionCookie?: string;
56
- }
57
- /**
58
- * OAuth2 provider config for bearer-token deploys.
59
- *
60
- * Deliberately secret-free: the client secret and refresh token live in the OS
61
- * keychain, so nothing here is unsafe to write to .dev_properties.json.
62
- */
63
- export interface OAuth2Config {
64
- authorizationEndpoint: string;
65
- tokenEndpoint: string;
66
- clientId: string;
67
- scopes?: string[];
68
- redirectPort?: number;
69
- }
70
- /**
71
- * Signing credentials (password is runtime-only, not persisted)
72
- */
73
- export interface SigningCredentials {
74
- username: string;
75
- password: string;
76
- certificateName?: string;
77
- }
78
- /**
79
- * Deployment configuration
80
- */
81
- export interface DeployConfig {
82
- domain: string;
83
- siteName: string;
84
- addonName: string;
85
- username: string;
86
- password?: string;
87
- accessToken?: string;
88
- sessionCookie?: string;
89
- useHTTP?: boolean;
90
- }
91
- /**
92
- * Production deployment configuration
93
- */
94
- export interface ProductionDeployConfig extends DeployConfig {
95
- activate?: boolean;
96
- }
97
- /**
98
- * Package.json sitevision_scripts_properties section
99
- */
100
- export interface SitevisionScriptsProperties {
101
- transpile?: boolean;
102
- transpilePackages?: string[];
103
- babel?: Record<string, unknown>;
104
- }
105
- /**
106
- * Full project information detected from the filesystem
107
- */
108
- export interface ProjectInfo {
109
- root: string;
110
- manifest: SitevisionManifest;
111
- hasDevProperties: boolean;
112
- hasSigningProperties: boolean;
113
- hasLegacyPassword: boolean;
114
- devProperties?: DevProperties;
115
- packageJson: PackageJson;
116
- hasSitevisionScripts: boolean;
117
- hasNodeModules: boolean;
118
- paths: ProjectPaths;
119
- }
120
- /**
121
- * Standard project paths
122
- */
123
- export interface ProjectPaths {
124
- root: string;
125
- src: string;
126
- static: string;
127
- build: string;
128
- dist: string;
129
- manifest: string;
130
- devProperties: string | null;
131
- packageJson: string;
132
- nodeModules: string;
133
- }
134
- /**
135
- * Partial package.json with fields we care about
136
- */
137
- export interface PackageJson {
138
- name?: string;
139
- version?: string;
140
- scripts?: Record<string, string>;
141
- dependencies?: Record<string, string>;
142
- devDependencies?: Record<string, string>;
143
- sitevision_scripts_properties?: SitevisionScriptsProperties;
144
- developmentDomain?: string;
145
- productionDomain?: string;
146
- addonName?: string;
147
- siteName?: string;
148
- }
149
- /**
150
- * REST API endpoints by app type
151
- */
152
- export interface ApiEndpoints {
153
- addon: string;
154
- import: string;
155
- }
156
- /**
157
- * API response from app signing
158
- */
159
- export interface SigningResponse {
160
- success: boolean;
161
- signedFilePath?: string;
162
- error?: string;
163
- }
164
- /**
165
- * API response from deployment
166
- */
167
- export interface DeployResponse {
168
- success: boolean;
169
- executableId?: string;
170
- message?: string;
171
- error?: string;
172
- authExpired?: boolean;
173
- }
174
- /**
175
- * API response from addon creation
176
- */
177
- export interface CreateAddonResponse {
178
- success: boolean;
179
- addonId?: string;
180
- error?: string;
181
- authExpired?: boolean;
182
- }
183
- /**
184
- * API response from activation
185
- */
186
- export interface ActivationResponse {
187
- success: boolean;
188
- error?: string;
189
- authExpired?: boolean;
190
- }
191
- /**
192
- * Build mode
193
- */
194
- export type BuildMode = 'development' | 'production';
195
- /**
196
- * Build options for webpack
197
- */
198
- export interface BuildOptions {
199
- mode: BuildMode;
200
- watch?: boolean;
201
- cssPrefix?: string;
202
- restApp?: boolean;
203
- }
204
- /**
205
- * Build result
206
- */
207
- export interface BuildResult {
208
- success: boolean;
209
- outputPath?: string;
210
- errors?: string[];
211
- warnings?: string[];
212
- stats?: {
213
- time: number;
214
- hash: string;
215
- assets: string[];
216
- };
217
- }
218
- /**
219
- * Watch callback for webpack watch mode
220
- */
221
- export type WatchCallback = (result: BuildResult) => void;
222
- /**
223
- * Command execution context
224
- */
225
- export interface CommandContext {
226
- project: ProjectInfo;
227
- flags: Record<string, unknown>;
228
- args: string[];
229
- }
230
- /**
231
- * Command definition
232
- */
233
- export interface Command {
234
- name: string;
235
- description: string;
236
- requiresProject: boolean;
237
- flags?: Record<string, CommandFlag>;
238
- execute: (context: CommandContext) => Promise<void>;
239
- }
240
- /**
241
- * Command flag definition
242
- */
243
- export interface CommandFlag {
244
- type: 'string' | 'boolean';
245
- description: string;
246
- alias?: string;
247
- default?: unknown;
248
- }
249
- /**
250
- * Process output types
251
- */
252
- export interface ProcessOutput {
253
- type: 'stdout' | 'stderr';
254
- data: string;
255
- }
256
- /**
257
- * Process execution result
258
- */
259
- export interface ProcessResult {
260
- exitCode: number;
261
- output: ProcessOutput[];
262
- }
263
- /**
264
- * HTTP request options
265
- */
266
- export interface HttpRequestOptions {
267
- method: 'GET' | 'POST' | 'PUT' | 'DELETE';
268
- headers?: Record<string, string>;
269
- body?: unknown;
270
- auth?: {
271
- username: string;
272
- password: string;
273
- };
274
- }
275
- /**
276
- * Generic result type for operations that can fail
277
- */
278
- export type Result<T, E = Error> = {
279
- success: true;
280
- data: T;
281
- } | {
282
- success: false;
283
- error: E;
284
- };
@@ -1,28 +0,0 @@
1
- /**
2
- * Shared CLI branding — the logo art and author line. Used both by the Ink
3
- * first-run welcome screen and the non-interactive "what's new" update banner,
4
- * so the two stay identical.
5
- */
6
- export declare const LOGO: string[];
7
- export declare const AUTHOR = "Rasmus S\u00F6derstr\u00F6m";
8
- /**
9
- * Big block-shadow "Sitevision CLI" wordmark, used by the animated startup
10
- * intro (see components/AnimatedLogo). It's ~120 columns wide, so callers
11
- * should only render it when the terminal is at least that wide — otherwise it
12
- * wraps and looks broken.
13
- */
14
- export declare const BIG_LOGO: string[];
15
- /** Display width of the widest BIG_LOGO line. */
16
- export declare const BIG_LOGO_WIDTH: number;
17
- /**
18
- * Compact "Sitevision CLI" wordmark, animated on terminals too narrow for
19
- * BIG_LOGO. ~72 columns wide.
20
- */
21
- export declare const SMALL_LOGO: string[];
22
- /** Display width of the widest SMALL_LOGO line. */
23
- export declare const SMALL_LOGO_WIDTH: number;
24
- /**
25
- * Print the logo + author line straight to stdout (non-interactive), mirroring
26
- * how the masthead is printed. Used for the update banner.
27
- */
28
- export declare function printBranding(): void;