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,9 @@
1
+ import React from 'react';
2
+ export type Status = 'pending' | 'running' | 'success' | 'error';
3
+ interface Props {
4
+ status: Status;
5
+ label: string;
6
+ message?: string;
7
+ }
8
+ export declare function StatusIndicator({ status, label, message }: Props): React.JSX.Element;
9
+ export {};
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+ import Spinner from 'ink-spinner';
4
+ export function StatusIndicator({ status, label, message }) {
5
+ const getIcon = () => {
6
+ switch (status) {
7
+ case 'pending':
8
+ return React.createElement(Text, { dimColor: true }, "\u25CB");
9
+ case 'running':
10
+ return (React.createElement(Text, { color: "cyan" },
11
+ React.createElement(Spinner, { type: "dots" })));
12
+ case 'success':
13
+ return React.createElement(Text, { color: "green" }, "\u2713");
14
+ case 'error':
15
+ return React.createElement(Text, { color: "red" }, "\u2717");
16
+ }
17
+ };
18
+ const getColor = () => {
19
+ switch (status) {
20
+ case 'pending':
21
+ return 'gray';
22
+ case 'running':
23
+ return 'cyan';
24
+ case 'success':
25
+ return 'green';
26
+ case 'error':
27
+ return 'red';
28
+ }
29
+ };
30
+ return (React.createElement(Box, null,
31
+ getIcon(),
32
+ React.createElement(Box, { marginLeft: 1 },
33
+ React.createElement(Text, { color: getColor(), bold: true }, label)),
34
+ message && (React.createElement(Box, { marginLeft: 1 },
35
+ React.createElement(Text, { dimColor: true }, message)))));
36
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface Props {
3
+ label: string;
4
+ defaultValue?: string;
5
+ placeholder?: string;
6
+ onSubmit: (value: string) => void;
7
+ onCancel?: () => void;
8
+ type?: 'text' | 'password';
9
+ }
10
+ export declare function TextInput({ label, defaultValue, placeholder, onSubmit, onCancel, type, }: Props): React.JSX.Element;
11
+ export {};
@@ -0,0 +1,37 @@
1
+ import React, { useState } from 'react';
2
+ import { Box, Text, useInput } from 'ink';
3
+ export function TextInput({ label, defaultValue = '', placeholder, onSubmit, onCancel, type = 'text', }) {
4
+ const [value, setValue] = useState(defaultValue);
5
+ useInput((input, key) => {
6
+ if (key.return) {
7
+ if (value === '' && defaultValue) {
8
+ onSubmit(defaultValue);
9
+ }
10
+ else {
11
+ onSubmit(value);
12
+ }
13
+ return;
14
+ }
15
+ if (key.escape && onCancel) {
16
+ onCancel();
17
+ return;
18
+ }
19
+ if (key.delete || key.backspace) {
20
+ setValue((prev) => prev.slice(0, -1));
21
+ return;
22
+ }
23
+ if (!key.ctrl && !key.meta) {
24
+ setValue((prev) => prev + input);
25
+ }
26
+ });
27
+ return (React.createElement(Box, { flexDirection: "column", padding: 1 },
28
+ React.createElement(Box, { marginBottom: 1 },
29
+ React.createElement(Text, { bold: true, color: "cyan" }, label)),
30
+ React.createElement(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1 },
31
+ React.createElement(Text, null, type === 'password' ? '*'.repeat(value.length) : value),
32
+ value === '' && placeholder && (React.createElement(Text, { dimColor: true }, placeholder))),
33
+ React.createElement(Box, { marginTop: 1 },
34
+ React.createElement(Text, { dimColor: true },
35
+ "Press Enter to submit",
36
+ onCancel ? ', Esc to cancel' : ''))));
37
+ }
@@ -0,0 +1,250 @@
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
+ * Sitevision app manifest (manifest.json)
16
+ */
17
+ export interface SitevisionManifest {
18
+ id: string;
19
+ name: string;
20
+ version: string;
21
+ type: AppType;
22
+ bundled?: boolean;
23
+ description?: string;
24
+ author?: string;
25
+ helpUrl?: string;
26
+ license?: string;
27
+ categories?: string[];
28
+ }
29
+ /**
30
+ * Development properties stored in .dev_properties.json
31
+ */
32
+ export interface DevProperties {
33
+ domain: string;
34
+ siteName: string;
35
+ addonName: string;
36
+ username: string;
37
+ password: string;
38
+ useHTTPForDevDeploy?: boolean;
39
+ signingUsername?: string;
40
+ certificateName?: string;
41
+ }
42
+ /**
43
+ * Signing credentials (password is runtime-only, not persisted)
44
+ */
45
+ export interface SigningCredentials {
46
+ username: string;
47
+ password: string;
48
+ certificateName?: string;
49
+ }
50
+ /**
51
+ * Deployment configuration
52
+ */
53
+ export interface DeployConfig {
54
+ domain: string;
55
+ siteName: string;
56
+ addonName: string;
57
+ username: string;
58
+ password: string;
59
+ useHTTP?: boolean;
60
+ }
61
+ /**
62
+ * Production deployment configuration
63
+ */
64
+ export interface ProductionDeployConfig extends DeployConfig {
65
+ activate?: boolean;
66
+ }
67
+ /**
68
+ * Package.json sitevision_scripts_properties section
69
+ */
70
+ export interface SitevisionScriptsProperties {
71
+ transpile?: boolean;
72
+ transpilePackages?: string[];
73
+ babel?: Record<string, unknown>;
74
+ }
75
+ /**
76
+ * Full project information detected from the filesystem
77
+ */
78
+ export interface ProjectInfo {
79
+ root: string;
80
+ manifest: SitevisionManifest;
81
+ hasDevProperties: boolean;
82
+ hasSigningProperties: boolean;
83
+ devProperties?: DevProperties;
84
+ packageJson: PackageJson;
85
+ hasSitevisionScripts: boolean;
86
+ hasNodeModules: boolean;
87
+ paths: ProjectPaths;
88
+ }
89
+ /**
90
+ * Standard project paths
91
+ */
92
+ export interface ProjectPaths {
93
+ root: string;
94
+ src: string;
95
+ static: string;
96
+ build: string;
97
+ dist: string;
98
+ manifest: string;
99
+ devProperties: string | null;
100
+ packageJson: string;
101
+ nodeModules: string;
102
+ }
103
+ /**
104
+ * Partial package.json with fields we care about
105
+ */
106
+ export interface PackageJson {
107
+ name?: string;
108
+ version?: string;
109
+ scripts?: Record<string, string>;
110
+ dependencies?: Record<string, string>;
111
+ devDependencies?: Record<string, string>;
112
+ sitevision_scripts_properties?: SitevisionScriptsProperties;
113
+ developmentDomain?: string;
114
+ productionDomain?: string;
115
+ addonName?: string;
116
+ siteName?: string;
117
+ }
118
+ /**
119
+ * REST API endpoints by app type
120
+ */
121
+ export interface ApiEndpoints {
122
+ addon: string;
123
+ import: string;
124
+ }
125
+ /**
126
+ * API response from app signing
127
+ */
128
+ export interface SigningResponse {
129
+ success: boolean;
130
+ signedFilePath?: string;
131
+ error?: string;
132
+ }
133
+ /**
134
+ * API response from deployment
135
+ */
136
+ export interface DeployResponse {
137
+ success: boolean;
138
+ executableId?: string;
139
+ message?: string;
140
+ error?: string;
141
+ }
142
+ /**
143
+ * API response from addon creation
144
+ */
145
+ export interface CreateAddonResponse {
146
+ success: boolean;
147
+ addonId?: string;
148
+ error?: string;
149
+ }
150
+ /**
151
+ * API response from activation
152
+ */
153
+ export interface ActivationResponse {
154
+ success: boolean;
155
+ error?: string;
156
+ }
157
+ /**
158
+ * Build mode
159
+ */
160
+ export type BuildMode = 'development' | 'production';
161
+ /**
162
+ * Build options for webpack
163
+ */
164
+ export interface BuildOptions {
165
+ mode: BuildMode;
166
+ watch?: boolean;
167
+ cssPrefix?: string;
168
+ restApp?: boolean;
169
+ }
170
+ /**
171
+ * Build result
172
+ */
173
+ export interface BuildResult {
174
+ success: boolean;
175
+ outputPath?: string;
176
+ errors?: string[];
177
+ warnings?: string[];
178
+ stats?: {
179
+ time: number;
180
+ hash: string;
181
+ assets: string[];
182
+ };
183
+ }
184
+ /**
185
+ * Watch callback for webpack watch mode
186
+ */
187
+ export type WatchCallback = (result: BuildResult) => void;
188
+ /**
189
+ * Command execution context
190
+ */
191
+ export interface CommandContext {
192
+ project: ProjectInfo;
193
+ flags: Record<string, unknown>;
194
+ args: string[];
195
+ }
196
+ /**
197
+ * Command definition
198
+ */
199
+ export interface Command {
200
+ name: string;
201
+ description: string;
202
+ requiresProject: boolean;
203
+ flags?: Record<string, CommandFlag>;
204
+ execute: (context: CommandContext) => Promise<void>;
205
+ }
206
+ /**
207
+ * Command flag definition
208
+ */
209
+ export interface CommandFlag {
210
+ type: 'string' | 'boolean';
211
+ description: string;
212
+ alias?: string;
213
+ default?: unknown;
214
+ }
215
+ /**
216
+ * Process output types
217
+ */
218
+ export interface ProcessOutput {
219
+ type: 'stdout' | 'stderr';
220
+ data: string;
221
+ }
222
+ /**
223
+ * Process execution result
224
+ */
225
+ export interface ProcessResult {
226
+ exitCode: number;
227
+ output: ProcessOutput[];
228
+ }
229
+ /**
230
+ * HTTP request options
231
+ */
232
+ export interface HttpRequestOptions {
233
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
234
+ headers?: Record<string, string>;
235
+ body?: unknown;
236
+ auth?: {
237
+ username: string;
238
+ password: string;
239
+ };
240
+ }
241
+ /**
242
+ * Generic result type for operations that can fail
243
+ */
244
+ export type Result<T, E = Error> = {
245
+ success: true;
246
+ data: T;
247
+ } | {
248
+ success: false;
249
+ error: E;
250
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Sitevision CLI - Shared Type Definitions
3
+ *
4
+ * This file contains all shared types used across the CLI.
5
+ */
6
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Prompt for password input with masked display
3
+ */
4
+ export declare function promptPassword(prompt: string): Promise<string>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Prompt for password input with masked display
3
+ */
4
+ export function promptPassword(prompt) {
5
+ return new Promise((resolve) => {
6
+ process.stdout.write(prompt);
7
+ const stdin = process.stdin;
8
+ stdin.setRawMode(true);
9
+ stdin.resume();
10
+ stdin.setEncoding('utf8');
11
+ let password = '';
12
+ const onData = (data) => {
13
+ // Handle each character in the input (supports paste)
14
+ for (const char of data) {
15
+ const charCode = char.charCodeAt(0);
16
+ if (charCode === 13 || charCode === 10) {
17
+ // Enter key
18
+ stdin.setRawMode(false);
19
+ stdin.removeListener('data', onData);
20
+ stdin.pause();
21
+ process.stdout.write('\n');
22
+ resolve(password);
23
+ return;
24
+ }
25
+ else if (charCode === 127 || charCode === 8) {
26
+ // Backspace
27
+ if (password.length > 0) {
28
+ password = password.slice(0, -1);
29
+ process.stdout.write('\b \b');
30
+ }
31
+ }
32
+ else if (charCode === 3) {
33
+ // Ctrl+C
34
+ process.exit();
35
+ }
36
+ else if (charCode >= 32) {
37
+ // Printable characters
38
+ password += char;
39
+ process.stdout.write('*');
40
+ }
41
+ }
42
+ };
43
+ stdin.on('data', onData);
44
+ });
45
+ }
@@ -0,0 +1,30 @@
1
+ import { EventEmitter } from 'events';
2
+ export interface ProcessOutput {
3
+ type: 'stdout' | 'stderr';
4
+ data: string;
5
+ }
6
+ export interface ProcessResult {
7
+ exitCode: number;
8
+ output: ProcessOutput[];
9
+ }
10
+ export declare class ProcessRunner extends EventEmitter {
11
+ private command;
12
+ private args;
13
+ private cwd?;
14
+ private interactive;
15
+ private customEnv?;
16
+ private process;
17
+ private output;
18
+ constructor(command: string, args?: string[], cwd?: string | undefined, interactive?: boolean, customEnv?: Record<string, string> | undefined);
19
+ run(): Promise<ProcessResult>;
20
+ kill(): void;
21
+ getOutput(): ProcessOutput[];
22
+ }
23
+ /**
24
+ * Run a sitevision-scripts command in the project directory
25
+ */
26
+ export declare function runSitevisionScript(scriptName: string, args?: string[], projectRoot?: string): ProcessRunner;
27
+ /**
28
+ * Run an NPM script
29
+ */
30
+ export declare function runNpmScript(scriptName: string, args?: string[], projectRoot?: string, customEnv?: Record<string, string>): ProcessRunner;
@@ -0,0 +1,119 @@
1
+ import { spawn } from 'child_process';
2
+ import { EventEmitter } from 'events';
3
+ export class ProcessRunner extends EventEmitter {
4
+ constructor(command, args = [], cwd, interactive = false, customEnv) {
5
+ super();
6
+ Object.defineProperty(this, "command", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: command
11
+ });
12
+ Object.defineProperty(this, "args", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: args
17
+ });
18
+ Object.defineProperty(this, "cwd", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: cwd
23
+ });
24
+ Object.defineProperty(this, "interactive", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: interactive
29
+ });
30
+ Object.defineProperty(this, "customEnv", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: customEnv
35
+ });
36
+ Object.defineProperty(this, "process", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: null
41
+ });
42
+ Object.defineProperty(this, "output", {
43
+ enumerable: true,
44
+ configurable: true,
45
+ writable: true,
46
+ value: []
47
+ });
48
+ }
49
+ run() {
50
+ return new Promise((resolve, reject) => {
51
+ this.process = spawn(this.command, this.args, {
52
+ cwd: this.cwd || process.cwd(),
53
+ env: { ...process.env, ...this.customEnv },
54
+ shell: true,
55
+ stdio: this.interactive ? 'inherit' : 'pipe',
56
+ });
57
+ // Only capture output if not in interactive mode
58
+ if (!this.interactive) {
59
+ this.process.stdout?.on('data', data => {
60
+ const output = {
61
+ type: 'stdout',
62
+ data: data.toString(),
63
+ };
64
+ this.output.push(output);
65
+ if (this.output.length > 1000) {
66
+ this.output.shift();
67
+ }
68
+ this.emit('output', output);
69
+ });
70
+ this.process.stderr?.on('data', data => {
71
+ const output = {
72
+ type: 'stderr',
73
+ data: data.toString(),
74
+ };
75
+ this.output.push(output);
76
+ if (this.output.length > 1000) {
77
+ this.output.shift();
78
+ }
79
+ this.emit('output', output);
80
+ });
81
+ }
82
+ this.process.on('error', error => {
83
+ this.emit('error', error);
84
+ reject(error);
85
+ });
86
+ this.process.on('close', code => {
87
+ const exitCode = code ?? 0;
88
+ this.emit('exit', exitCode);
89
+ resolve({
90
+ exitCode,
91
+ output: this.output,
92
+ });
93
+ });
94
+ });
95
+ }
96
+ kill() {
97
+ if (this.process) {
98
+ this.process.kill('SIGTERM');
99
+ }
100
+ }
101
+ getOutput() {
102
+ return this.output;
103
+ }
104
+ }
105
+ /**
106
+ * Run a sitevision-scripts command in the project directory
107
+ */
108
+ export function runSitevisionScript(scriptName, args = [], projectRoot) {
109
+ // Check if sitevision-scripts is available locally
110
+ const runner = new ProcessRunner('npm', ['run', scriptName, '--', ...args], projectRoot);
111
+ return runner;
112
+ }
113
+ /**
114
+ * Run an NPM script
115
+ */
116
+ export function runNpmScript(scriptName, args = [], projectRoot, customEnv) {
117
+ const runner = new ProcessRunner('npm', ['run', scriptName, ...args], projectRoot, false, customEnv);
118
+ return runner;
119
+ }
@@ -0,0 +1,103 @@
1
+ import type { SitevisionManifest, DevProperties, ProjectPaths, SimpleAppType, PackageJson, ApiEndpoints } from '../types/index.js';
2
+ export type { SitevisionManifest, DevProperties } from '../types/index.js';
3
+ /**
4
+ * Project information with paths
5
+ */
6
+ export interface ProjectInfo {
7
+ root: string;
8
+ manifest: SitevisionManifest;
9
+ hasDevProperties: boolean;
10
+ hasSigningProperties: boolean;
11
+ devProperties?: DevProperties;
12
+ packageJson: PackageJson;
13
+ hasSitevisionScripts: boolean;
14
+ hasNodeModules: boolean;
15
+ paths: ProjectPaths;
16
+ }
17
+ /**
18
+ * Get standard project paths for a given root directory
19
+ */
20
+ export declare function getProjectPaths(root: string, manifestPath: string, devPropertiesPath: string | null): ProjectPaths;
21
+ /**
22
+ * Find the dev properties file path (supports both naming conventions)
23
+ */
24
+ export declare function findDevPropertiesPath(root: string): string | null;
25
+ /**
26
+ * Get the default dev properties path (for creating new files)
27
+ */
28
+ export declare function getDefaultDevPropertiesPath(root: string): string;
29
+ /**
30
+ * Get the full app ID including any prefix/suffix from environment
31
+ *
32
+ * This combines: prefix + baseId + suffix
33
+ * Used for generating zip filenames and deployment identifiers
34
+ */
35
+ export declare function getFullAppId(baseId: string): string;
36
+ /**
37
+ * Get the zip filename for an app
38
+ */
39
+ export declare function getZipFilename(manifest: SitevisionManifest): string;
40
+ /**
41
+ * Get the signed zip filename for an app
42
+ */
43
+ export declare function getSignedZipFilename(manifest: SitevisionManifest): string;
44
+ /**
45
+ * Get the full path to the zip file in dist/
46
+ */
47
+ export declare function getZipPath(projectRoot: string, manifest: SitevisionManifest): string;
48
+ /**
49
+ * Get the full path to the signed zip file in dist/
50
+ */
51
+ export declare function getSignedZipPath(projectRoot: string, manifest: SitevisionManifest): string;
52
+ /**
53
+ * Get API endpoints for the given app type
54
+ */
55
+ export declare function getApiEndpoints(appType: SimpleAppType): ApiEndpoints;
56
+ /**
57
+ * Build the base URL for API requests
58
+ */
59
+ export declare function buildApiBaseUrl(domain: string, siteName: string, useHTTP?: boolean): string;
60
+ /**
61
+ * Build the addon endpoint URL
62
+ */
63
+ export declare function buildAddonEndpointUrl(domain: string, siteName: string, appType: SimpleAppType, useHTTP?: boolean): string;
64
+ /**
65
+ * Build the import endpoint URL
66
+ */
67
+ export declare function buildImportEndpointUrl(domain: string, siteName: string, addonName: string, appType: SimpleAppType, useHTTP?: boolean): string;
68
+ /**
69
+ * Detect if the current directory is a Sitevision project
70
+ */
71
+ export declare function detectProject(cwd?: string): ProjectInfo | null;
72
+ /**
73
+ * Validate that we're in a Sitevision project directory
74
+ */
75
+ export declare function requireProject(cwd?: string): ProjectInfo;
76
+ /**
77
+ * Get the app type (web, widget, rest)
78
+ */
79
+ export declare function getAppType(manifest: SitevisionManifest): SimpleAppType;
80
+ /**
81
+ * Check if the app uses webpack bundling
82
+ */
83
+ export declare function isBundledApp(manifest: SitevisionManifest): boolean;
84
+ /**
85
+ * Read and parse the dev properties file
86
+ */
87
+ export declare function readDevProperties(projectRoot: string): DevProperties | null;
88
+ /**
89
+ * Write dev properties to file
90
+ */
91
+ export declare function writeDevProperties(projectRoot: string, properties: DevProperties): void;
92
+ /**
93
+ * Ensure the dist directory exists
94
+ */
95
+ export declare function ensureDistDir(projectRoot: string): string;
96
+ /**
97
+ * Ensure the build directory exists
98
+ */
99
+ export declare function ensureBuildDir(projectRoot: string): string;
100
+ /**
101
+ * Clean the build directory
102
+ */
103
+ export declare function cleanBuildDir(projectRoot: string): void;