sitevision-cli 0.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 (54) hide show
  1. package/dist/app.d.ts +7 -0
  2. package/dist/app.js +180 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +95 -0
  5. package/dist/commands/build.d.ts +12 -0
  6. package/dist/commands/build.js +168 -0
  7. package/dist/commands/deploy.d.ts +17 -0
  8. package/dist/commands/deploy.js +162 -0
  9. package/dist/commands/dev.d.ts +15 -0
  10. package/dist/commands/dev.js +291 -0
  11. package/dist/commands/index.d.ts +4 -0
  12. package/dist/commands/index.js +20 -0
  13. package/dist/commands/info.d.ts +2 -0
  14. package/dist/commands/info.js +66 -0
  15. package/dist/commands/setup-signing.d.ts +2 -0
  16. package/dist/commands/setup-signing.js +82 -0
  17. package/dist/commands/sign.d.ts +14 -0
  18. package/dist/commands/sign.js +103 -0
  19. package/dist/commands/types.d.ts +18 -0
  20. package/dist/commands/types.js +1 -0
  21. package/dist/components/DevPropertiesForm.d.ts +11 -0
  22. package/dist/components/DevPropertiesForm.js +87 -0
  23. package/dist/components/InfoScreen.d.ts +8 -0
  24. package/dist/components/InfoScreen.js +60 -0
  25. package/dist/components/MainMenu.d.ts +8 -0
  26. package/dist/components/MainMenu.js +138 -0
  27. package/dist/components/PasswordInput.d.ts +8 -0
  28. package/dist/components/PasswordInput.js +30 -0
  29. package/dist/components/ProcessOutput.d.ts +7 -0
  30. package/dist/components/ProcessOutput.js +32 -0
  31. package/dist/components/SetupFlow.d.ts +8 -0
  32. package/dist/components/SetupFlow.js +194 -0
  33. package/dist/components/SigningPropertiesForm.d.ts +8 -0
  34. package/dist/components/SigningPropertiesForm.js +49 -0
  35. package/dist/components/StatusIndicator.d.ts +9 -0
  36. package/dist/components/StatusIndicator.js +36 -0
  37. package/dist/components/TextInput.d.ts +11 -0
  38. package/dist/components/TextInput.js +37 -0
  39. package/dist/types/index.d.ts +250 -0
  40. package/dist/types/index.js +6 -0
  41. package/dist/utils/password-prompt.d.ts +4 -0
  42. package/dist/utils/password-prompt.js +45 -0
  43. package/dist/utils/process-runner.d.ts +30 -0
  44. package/dist/utils/process-runner.js +119 -0
  45. package/dist/utils/project-detection.d.ts +103 -0
  46. package/dist/utils/project-detection.js +287 -0
  47. package/dist/utils/sitevision-api.d.ts +56 -0
  48. package/dist/utils/sitevision-api.js +393 -0
  49. package/dist/utils/webpack-runner.d.ts +75 -0
  50. package/dist/utils/webpack-runner.js +313 -0
  51. package/dist/utils/zip.d.ts +64 -0
  52. package/dist/utils/zip.js +246 -0
  53. package/package.json +59 -0
  54. package/readme.md +196 -0
@@ -0,0 +1,287 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ // =============================================================================
4
+ // PATH UTILITIES
5
+ // =============================================================================
6
+ /**
7
+ * Get standard project paths for a given root directory
8
+ */
9
+ export function getProjectPaths(root, manifestPath, devPropertiesPath) {
10
+ return {
11
+ root,
12
+ src: path.join(root, 'src'),
13
+ static: path.join(root, 'static'),
14
+ build: path.join(root, 'build'),
15
+ dist: path.join(root, 'dist'),
16
+ manifest: manifestPath,
17
+ devProperties: devPropertiesPath,
18
+ packageJson: path.join(root, 'package.json'),
19
+ nodeModules: path.join(root, 'node_modules'),
20
+ };
21
+ }
22
+ /**
23
+ * Find the dev properties file path (supports both naming conventions)
24
+ */
25
+ export function findDevPropertiesPath(root) {
26
+ const paths = [
27
+ path.join(root, '.dev_properties.json'),
28
+ path.join(root, '.dev-properties.json'),
29
+ ];
30
+ for (const p of paths) {
31
+ if (fs.existsSync(p)) {
32
+ return p;
33
+ }
34
+ }
35
+ return null;
36
+ }
37
+ /**
38
+ * Get the default dev properties path (for creating new files)
39
+ */
40
+ export function getDefaultDevPropertiesPath(root) {
41
+ return path.join(root, '.dev_properties.json');
42
+ }
43
+ /**
44
+ * Get app ID configuration from environment or defaults
45
+ */
46
+ function getAppIdConfig() {
47
+ return {
48
+ prefix: process.env['SITEVISION_APP_ID_PREFIX'] || '',
49
+ suffix: process.env['SITEVISION_APP_ID_SUFFIX'] || '',
50
+ };
51
+ }
52
+ /**
53
+ * Get the full app ID including any prefix/suffix from environment
54
+ *
55
+ * This combines: prefix + baseId + suffix
56
+ * Used for generating zip filenames and deployment identifiers
57
+ */
58
+ export function getFullAppId(baseId) {
59
+ const config = getAppIdConfig();
60
+ return `${config.prefix}${baseId}${config.suffix}`;
61
+ }
62
+ /**
63
+ * Get the zip filename for an app
64
+ */
65
+ export function getZipFilename(manifest) {
66
+ return `${getFullAppId(manifest.id)}.zip`;
67
+ }
68
+ /**
69
+ * Get the signed zip filename for an app
70
+ */
71
+ export function getSignedZipFilename(manifest) {
72
+ return `${getFullAppId(manifest.id)}-signed.zip`;
73
+ }
74
+ /**
75
+ * Get the full path to the zip file in dist/
76
+ */
77
+ export function getZipPath(projectRoot, manifest) {
78
+ return path.join(projectRoot, 'dist', getZipFilename(manifest));
79
+ }
80
+ /**
81
+ * Get the full path to the signed zip file in dist/
82
+ */
83
+ export function getSignedZipPath(projectRoot, manifest) {
84
+ return path.join(projectRoot, 'dist', getSignedZipFilename(manifest));
85
+ }
86
+ // =============================================================================
87
+ // API ENDPOINT UTILITIES
88
+ // =============================================================================
89
+ /**
90
+ * Get API endpoints for the given app type
91
+ */
92
+ export function getApiEndpoints(appType) {
93
+ switch (appType) {
94
+ case 'web':
95
+ return {
96
+ addon: 'custommodule',
97
+ import: 'webAppImport',
98
+ };
99
+ case 'widget':
100
+ return {
101
+ addon: 'widgetcustommodule',
102
+ import: 'webAppImport',
103
+ };
104
+ case 'rest':
105
+ return {
106
+ addon: 'headlesscustommodule',
107
+ import: 'restAppImport',
108
+ };
109
+ }
110
+ }
111
+ /**
112
+ * Build the base URL for API requests
113
+ */
114
+ export function buildApiBaseUrl(domain, siteName, useHTTP = false) {
115
+ const protocol = useHTTP ? 'http' : 'https';
116
+ return `${protocol}://${domain}/rest-api/1/0/${encodeURIComponent(siteName)}`;
117
+ }
118
+ /**
119
+ * Build the addon endpoint URL
120
+ */
121
+ export function buildAddonEndpointUrl(domain, siteName, appType, useHTTP = false) {
122
+ const baseUrl = buildApiBaseUrl(domain, siteName, useHTTP);
123
+ const endpoints = getApiEndpoints(appType);
124
+ return `${baseUrl}/Addon%20Repository/${endpoints.addon}`;
125
+ }
126
+ /**
127
+ * Build the import endpoint URL
128
+ */
129
+ export function buildImportEndpointUrl(domain, siteName, addonName, appType, useHTTP = false) {
130
+ const baseUrl = buildApiBaseUrl(domain, siteName, useHTTP);
131
+ const endpoints = getApiEndpoints(appType);
132
+ return `${baseUrl}/Addon%20Repository/${encodeURIComponent(addonName)}/${endpoints.import}`;
133
+ }
134
+ // =============================================================================
135
+ // PROJECT DETECTION
136
+ // =============================================================================
137
+ /**
138
+ * Detect if the current directory is a Sitevision project
139
+ */
140
+ export function detectProject(cwd = process.cwd()) {
141
+ try {
142
+ // Look for manifest.json in multiple locations (current, static/, src/)
143
+ const manifestPaths = [
144
+ path.join(cwd, 'manifest.json'),
145
+ path.join(cwd, 'static', 'manifest.json'),
146
+ path.join(cwd, 'src', 'manifest.json'),
147
+ ];
148
+ let manifestPath = null;
149
+ let manifest = null;
150
+ for (const p of manifestPaths) {
151
+ if (fs.existsSync(p)) {
152
+ manifestPath = p;
153
+ manifest = JSON.parse(fs.readFileSync(p, 'utf-8'));
154
+ break;
155
+ }
156
+ }
157
+ if (!manifest || !manifestPath) {
158
+ return null;
159
+ }
160
+ // Check for package.json
161
+ const packageJsonPath = path.join(cwd, 'package.json');
162
+ if (!fs.existsSync(packageJsonPath)) {
163
+ return null;
164
+ }
165
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
166
+ // Check if sitevision-scripts is installed
167
+ const hasSitevisionScripts = Boolean(packageJson.dependencies?.['@sitevision/scripts'] ||
168
+ packageJson.devDependencies?.['@sitevision/scripts']);
169
+ // Check for node_modules
170
+ const nodeModulesPath = path.join(cwd, 'node_modules');
171
+ const hasNodeModules = fs.existsSync(nodeModulesPath);
172
+ // Check for dev properties
173
+ const devPropertiesPath = findDevPropertiesPath(cwd);
174
+ let devProperties;
175
+ let hasDevProperties = false;
176
+ if (devPropertiesPath) {
177
+ hasDevProperties = true;
178
+ try {
179
+ devProperties = JSON.parse(fs.readFileSync(devPropertiesPath, 'utf-8'));
180
+ }
181
+ catch {
182
+ // Invalid dev properties file
183
+ }
184
+ }
185
+ // Check if signing properties are configured (only username is stored, password is entered at runtime)
186
+ const hasSigningProperties = Boolean(devProperties?.signingUsername);
187
+ // Build paths object
188
+ const paths = getProjectPaths(cwd, manifestPath, devPropertiesPath);
189
+ return {
190
+ root: cwd,
191
+ manifest,
192
+ hasDevProperties,
193
+ hasSigningProperties,
194
+ devProperties,
195
+ packageJson,
196
+ hasSitevisionScripts,
197
+ hasNodeModules,
198
+ paths,
199
+ };
200
+ }
201
+ catch {
202
+ return null;
203
+ }
204
+ }
205
+ /**
206
+ * Validate that we're in a Sitevision project directory
207
+ */
208
+ export function requireProject(cwd) {
209
+ const project = detectProject(cwd);
210
+ if (!project) {
211
+ throw new Error('Not a Sitevision project. Run this command inside a Sitevision app directory.');
212
+ }
213
+ return project;
214
+ }
215
+ /**
216
+ * Get the app type (web, widget, rest)
217
+ */
218
+ export function getAppType(manifest) {
219
+ const type = manifest.type.toLowerCase();
220
+ if (type.startsWith('web')) {
221
+ return 'web';
222
+ }
223
+ if (type.startsWith('widget')) {
224
+ return 'widget';
225
+ }
226
+ if (type.startsWith('rest')) {
227
+ return 'rest';
228
+ }
229
+ throw new Error(`Unknown app type: ${manifest.type}`);
230
+ }
231
+ /**
232
+ * Check if the app uses webpack bundling
233
+ */
234
+ export function isBundledApp(manifest) {
235
+ return manifest.bundled === true;
236
+ }
237
+ /**
238
+ * Read and parse the dev properties file
239
+ */
240
+ export function readDevProperties(projectRoot) {
241
+ const devPropertiesPath = findDevPropertiesPath(projectRoot);
242
+ if (!devPropertiesPath) {
243
+ return null;
244
+ }
245
+ try {
246
+ return JSON.parse(fs.readFileSync(devPropertiesPath, 'utf-8'));
247
+ }
248
+ catch {
249
+ return null;
250
+ }
251
+ }
252
+ /**
253
+ * Write dev properties to file
254
+ */
255
+ export function writeDevProperties(projectRoot, properties) {
256
+ const devPropertiesPath = findDevPropertiesPath(projectRoot) || getDefaultDevPropertiesPath(projectRoot);
257
+ fs.writeFileSync(devPropertiesPath, JSON.stringify(properties, null, 2));
258
+ }
259
+ /**
260
+ * Ensure the dist directory exists
261
+ */
262
+ export function ensureDistDir(projectRoot) {
263
+ const distPath = path.join(projectRoot, 'dist');
264
+ if (!fs.existsSync(distPath)) {
265
+ fs.mkdirSync(distPath, { recursive: true });
266
+ }
267
+ return distPath;
268
+ }
269
+ /**
270
+ * Ensure the build directory exists
271
+ */
272
+ export function ensureBuildDir(projectRoot) {
273
+ const buildPath = path.join(projectRoot, 'build');
274
+ if (!fs.existsSync(buildPath)) {
275
+ fs.mkdirSync(buildPath, { recursive: true });
276
+ }
277
+ return buildPath;
278
+ }
279
+ /**
280
+ * Clean the build directory
281
+ */
282
+ export function cleanBuildDir(projectRoot) {
283
+ const buildPath = path.join(projectRoot, 'build');
284
+ if (fs.existsSync(buildPath)) {
285
+ fs.rmSync(buildPath, { recursive: true, force: true });
286
+ }
287
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Sitevision API Client
3
+ *
4
+ * Handles all API interactions with Sitevision servers:
5
+ * - Signing apps via developer.sitevision.se
6
+ * - Deploying to development environments
7
+ * - Deploying to production environments
8
+ * - Creating addons
9
+ * - Activating production apps
10
+ */
11
+ import type { SigningCredentials, DeployConfig, ProductionDeployConfig, SigningResponse, DeployResponse, CreateAddonResponse, ActivationResponse, SimpleAppType } from '../types/index.js';
12
+ /**
13
+ * Create Basic Auth header value
14
+ */
15
+ declare function createBasicAuth(username: string, password: string): string;
16
+ /**
17
+ * Sign an app via developer.sitevision.se
18
+ *
19
+ * @param zipPath - Path to the unsigned zip file
20
+ * @param credentials - Signing credentials
21
+ * @param outputPath - Path to write the signed zip file
22
+ */
23
+ export declare function signApp(zipPath: string, credentials: SigningCredentials, outputPath: string): Promise<SigningResponse>;
24
+ /**
25
+ * Deploy an app to a development environment
26
+ *
27
+ * @param zipPath - Path to the zip file (signed or unsigned)
28
+ * @param config - Deployment configuration
29
+ * @param appType - The app type (web, widget, rest)
30
+ * @param force - Whether to force deploy (overwrite existing)
31
+ */
32
+ export declare function deployApp(zipPath: string, config: DeployConfig, appType: SimpleAppType, force?: boolean): Promise<DeployResponse>;
33
+ /**
34
+ * Deploy an app to production
35
+ *
36
+ * @param signedZipPath - Path to the SIGNED zip file (required for production)
37
+ * @param config - Production deployment configuration
38
+ * @param appType - The app type (web, widget, rest)
39
+ */
40
+ export declare function deployProduction(signedZipPath: string, config: ProductionDeployConfig, appType: SimpleAppType): Promise<DeployResponse>;
41
+ /**
42
+ * Create a new addon on a Sitevision site
43
+ *
44
+ * @param config - Deployment configuration
45
+ * @param appType - The app type (web, widget, rest)
46
+ */
47
+ export declare function createAddon(config: DeployConfig, appType: SimpleAppType): Promise<CreateAddonResponse>;
48
+ /**
49
+ * Activate a deployed production app
50
+ *
51
+ * @param executableId - The executable ID returned from deployment
52
+ * @param config - Deployment configuration
53
+ * @param appType - The app type (web, widget, rest)
54
+ */
55
+ export declare function activateApp(executableId: string, config: DeployConfig, _appType: SimpleAppType): Promise<ActivationResponse>;
56
+ export { createBasicAuth };