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.
- package/dist/app.d.ts +7 -0
- package/dist/app.js +180 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +95 -0
- package/dist/commands/build.d.ts +12 -0
- package/dist/commands/build.js +168 -0
- package/dist/commands/deploy.d.ts +17 -0
- package/dist/commands/deploy.js +162 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.js +291 -0
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +20 -0
- package/dist/commands/info.d.ts +2 -0
- package/dist/commands/info.js +66 -0
- package/dist/commands/setup-signing.d.ts +2 -0
- package/dist/commands/setup-signing.js +82 -0
- package/dist/commands/sign.d.ts +14 -0
- package/dist/commands/sign.js +103 -0
- package/dist/commands/types.d.ts +18 -0
- package/dist/commands/types.js +1 -0
- package/dist/components/DevPropertiesForm.d.ts +11 -0
- package/dist/components/DevPropertiesForm.js +87 -0
- package/dist/components/InfoScreen.d.ts +8 -0
- package/dist/components/InfoScreen.js +60 -0
- package/dist/components/MainMenu.d.ts +8 -0
- package/dist/components/MainMenu.js +138 -0
- package/dist/components/PasswordInput.d.ts +8 -0
- package/dist/components/PasswordInput.js +30 -0
- package/dist/components/ProcessOutput.d.ts +7 -0
- package/dist/components/ProcessOutput.js +32 -0
- package/dist/components/SetupFlow.d.ts +8 -0
- package/dist/components/SetupFlow.js +194 -0
- package/dist/components/SigningPropertiesForm.d.ts +8 -0
- package/dist/components/SigningPropertiesForm.js +49 -0
- package/dist/components/StatusIndicator.d.ts +9 -0
- package/dist/components/StatusIndicator.js +36 -0
- package/dist/components/TextInput.d.ts +11 -0
- package/dist/components/TextInput.js +37 -0
- package/dist/types/index.d.ts +250 -0
- package/dist/types/index.js +6 -0
- package/dist/utils/password-prompt.d.ts +4 -0
- package/dist/utils/password-prompt.js +45 -0
- package/dist/utils/process-runner.d.ts +30 -0
- package/dist/utils/process-runner.js +119 -0
- package/dist/utils/project-detection.d.ts +103 -0
- package/dist/utils/project-detection.js +287 -0
- package/dist/utils/sitevision-api.d.ts +56 -0
- package/dist/utils/sitevision-api.js +393 -0
- package/dist/utils/webpack-runner.d.ts +75 -0
- package/dist/utils/webpack-runner.js +313 -0
- package/dist/utils/zip.d.ts +64 -0
- package/dist/utils/zip.js +246 -0
- package/package.json +59 -0
- 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 };
|